mirror of
https://github.com/StarWishsama/Slimefun4.git
synced 2024-09-20 11:45:51 +00:00
Merge branch 'master' of https://github.com/Slimefun/Slimefun4.git into
api/machine-operations Conflicts: src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/reactors/Reactor.java src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/geo/GEOMiner.java
This commit is contained in:
commit
44a6d15d18
3
.github/renovate.json
vendored
3
.github/renovate.json
vendored
@ -1,8 +1,5 @@
|
|||||||
{
|
{
|
||||||
"extends": [
|
"extends": [
|
||||||
"config:base"
|
"config:base"
|
||||||
],
|
|
||||||
"labels": [
|
|
||||||
"🚨 Dependency Update"
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
7
.github/workflows/closed-issues-reason.yml
vendored
7
.github/workflows/closed-issues-reason.yml
vendored
@ -6,8 +6,11 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
comment:
|
comment:
|
||||||
|
|
||||||
|
name: Comment on Issue
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
if: contains(github.event.issue.labels.*.name, '🐞 Bug Report')
|
if: contains(github.event.issue.labels.*.name, '🐞 Bug Report')
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Query recent commits
|
- name: Query recent commits
|
||||||
uses: TheBusyBiscuit/recently-closed-issues@1.1.0
|
uses: TheBusyBiscuit/recently-closed-issues@1.1.0
|
||||||
@ -44,8 +47,8 @@ jobs:
|
|||||||
* [ ] Your issue has already been reported before, 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 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 separate issue for each bug you encountered, so we can properly handle them individually.
|
* [ ] You seem to be reporting multiple bugs at once. Please make a separate 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.
|
* [ ] Your issue has already been fixed in a later version of Slimefun, you should update.
|
||||||
* [ ] You are using an outdated and unsupported version of Slimefun / CS-CoreLib, again, you should update.
|
* [ ] You are using an outdated and unsupported version of Slimefun, again, you should update.
|
||||||
* [ ] You are using an unofficially modified build of Slimefun. We only support official versions of Slimefun - for obvious reasons.
|
* [ ] You are using an unofficially modified build of Slimefun. We only support official versions of Slimefun - for obvious reasons.
|
||||||
* [ ] 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 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 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.
|
||||||
|
17
.github/workflows/pr-labels.yml
vendored
17
.github/workflows/pr-labels.yml
vendored
@ -10,34 +10,36 @@ jobs:
|
|||||||
|
|
||||||
name: Pull Request Labels
|
name: Pull Request Labels
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
if: github.repository == 'Slimefun/Slimefun4' && github.actor != 'gitlocalize-app[bot]' && github.actor != 'renovate[bot]'
|
if: github.repository == 'Slimefun/Slimefun4' && github.actor != 'gitlocalize-app[bot]'
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: WalshyDev/pr-labels@v1.1
|
- uses: WalshyDev/pr-labels@v1.1
|
||||||
id: labeller
|
id: labeller
|
||||||
name: Apply labels based on branch
|
name: Apply labels based on branch
|
||||||
with:
|
with:
|
||||||
token: "${{ secrets.ACCESS_TOKEN }}"
|
token: "${{ secrets.GITHUB_TOKEN }}"
|
||||||
|
renovate: '🚨 Dependency Update'
|
||||||
feature: '🎈 Feature'
|
feature: '🎈 Feature'
|
||||||
fix: '✨ Fix'
|
fix: '✨ Fix'
|
||||||
chore: '🧹 Chores'
|
chore: '🧹 Chores'
|
||||||
performance: '💡 Performance Optimization'
|
performance: '💡 Performance Optimization'
|
||||||
api: '🔧 API'
|
api: '🔧 API'
|
||||||
|
compatibility: '🤝 Compatibility'
|
||||||
|
|
||||||
- uses: thollander/actions-comment-pull-request@1.0.1
|
- uses: thollander/actions-comment-pull-request@1.0.1
|
||||||
name: Comment the applied label
|
name: Leave a comment about the applied label
|
||||||
if: ${{ steps.labeller.outputs.applied != 0 }}
|
if: ${{ steps.labeller.outputs.applied != 0 }}
|
||||||
with:
|
with:
|
||||||
GITHUB_TOKEN: ${{ secrets.ACCESS_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
message: |
|
message: |
|
||||||
Your Pull Request was automatically labelled as: ${{ steps.labeller.outputs.applied }}
|
Your Pull Request was automatically labelled as: "${{ steps.labeller.outputs.applied }}"
|
||||||
Thank you for contributing to this project! ❤️
|
Thank you for contributing to this project! ❤️
|
||||||
|
|
||||||
- uses: thollander/actions-comment-pull-request@1.0.1
|
- uses: thollander/actions-comment-pull-request@1.0.1
|
||||||
name: Comment the applied label
|
name: Leave a comment about our branch naming convention
|
||||||
if: ${{ steps.labeller.outputs.applied == 0 }}
|
if: ${{ steps.labeller.outputs.applied == 0 }}
|
||||||
with:
|
with:
|
||||||
GITHUB_TOKEN: ${{ secrets.ACCESS_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
message: |
|
message: |
|
||||||
**Pro Tip!**
|
**Pro Tip!**
|
||||||
You can help us label your Pull Requests by using the following branch naming convention next time you create a pull request. ❤️
|
You can help us label your Pull Requests by using the following branch naming convention next time you create a pull request. ❤️
|
||||||
@ -48,6 +50,7 @@ jobs:
|
|||||||
`chore/**` | 🧹 Chores
|
`chore/**` | 🧹 Chores
|
||||||
`api/**` | 🔧 API
|
`api/**` | 🔧 API
|
||||||
`performance/**` | 💡 Performance Optimization
|
`performance/**` | 💡 Performance Optimization
|
||||||
|
`compatibility/**` | 🤝 Compatibility
|
||||||
<hr>
|
<hr>
|
||||||
If your changes do not fall into any of these categories, don't worry.
|
If your changes do not fall into any of these categories, don't worry.
|
||||||
You can just ignore this message in that case! 👀
|
You can just ignore this message in that case! 👀
|
||||||
|
45
CHANGELOG.md
45
CHANGELOG.md
@ -1,4 +1,5 @@
|
|||||||
# Table of contents
|
# Table of contents
|
||||||
|
- [Release Candidate 21 (TBD)](#release-candidate-21-tbd)
|
||||||
- [Release Candidate 20 (30 Jan 2021)](#release-candidate-20-30-jan-2021)
|
- [Release Candidate 20 (30 Jan 2021)](#release-candidate-20-30-jan-2021)
|
||||||
- [Release Candidate 19 (11 Jan 2021)](#release-candidate-19-11-jan-2021)
|
- [Release Candidate 19 (11 Jan 2021)](#release-candidate-19-11-jan-2021)
|
||||||
- [Release Candidate 18 (03 Dec 2020)](#release-candidate-18-03-dec-2020)
|
- [Release Candidate 18 (03 Dec 2020)](#release-candidate-18-03-dec-2020)
|
||||||
@ -20,6 +21,46 @@
|
|||||||
- [Release Candidate 2 (29 Sep 2019)](#release-candidate-2-29-sep-2019)
|
- [Release Candidate 2 (29 Sep 2019)](#release-candidate-2-29-sep-2019)
|
||||||
- [Release Candidate 1 (26 Sep 2019)](#release-candidate-1-26-sep-2019)
|
- [Release Candidate 1 (26 Sep 2019)](#release-candidate-1-26-sep-2019)
|
||||||
|
|
||||||
|
## Release Candidate 21 (TBD)
|
||||||
|
|
||||||
|
#### Additions
|
||||||
|
* Nether Wart Blocks can now be turned into Nether Warts using a Grind Stone
|
||||||
|
* Added an option to allow Talismans to send their notifications via the Actionbar
|
||||||
|
* (API) Added support for nested Categories
|
||||||
|
* (API) Added ExplosiveToolBreakBlocksEvent
|
||||||
|
* Added an option to enable/disable water in the nether via a crucible
|
||||||
|
* /sf versions now shows the Java version and some useful tooltips
|
||||||
|
|
||||||
|
#### Changes
|
||||||
|
* Deprecated Automatic Crafting Chamber
|
||||||
|
* Performance Improvements and Optimizations for Cobblestone/Stone/Basalt generators and mining androids
|
||||||
|
* Androids operating on a Cobblestone/Stone/Basalt generator now work faster
|
||||||
|
* (API) Improvements to the BlockBreakHandler
|
||||||
|
* (API) Deprecated SlimefunBlockHandler
|
||||||
|
|
||||||
|
#### Fixes
|
||||||
|
* Fixed #2794
|
||||||
|
* Fixed #2793
|
||||||
|
* Fixed #2809
|
||||||
|
* Fixed a small exception which gets thrown when Slimefun is disabled due to an invalid environment
|
||||||
|
* Fixed #2810
|
||||||
|
* Fixed #2804
|
||||||
|
* Fixed #2817
|
||||||
|
* Fixed exceptions with inventories not being printed using the logger of the addon that caused it
|
||||||
|
* Fixed #2818
|
||||||
|
* Fixed a duplication glitch with the Woodcutter Android
|
||||||
|
* Fixed #2839
|
||||||
|
* Fixed #2849
|
||||||
|
* Fixed #2851
|
||||||
|
* Fixed #2852
|
||||||
|
* Fixed some issues with the Book Binder
|
||||||
|
* Fixed #2805
|
||||||
|
* Fixed #2861
|
||||||
|
* Fixed #2856
|
||||||
|
* Fixed #2876
|
||||||
|
* Fixed #2877
|
||||||
|
* Fixed #2878
|
||||||
|
|
||||||
## Release Candidate 20 (30 Jan 2021)
|
## Release Candidate 20 (30 Jan 2021)
|
||||||
|
|
||||||
#### Additions
|
#### Additions
|
||||||
@ -36,6 +77,8 @@
|
|||||||
|
|
||||||
#### Fixes
|
#### Fixes
|
||||||
* Fixed elevator floor order
|
* Fixed elevator floor order
|
||||||
|
* Fixed "block-explosions" (e.g. beds in Nether) not properly respecting explosion-resistant blocks
|
||||||
|
* Fixed #2560
|
||||||
* Fixed #2449
|
* Fixed #2449
|
||||||
* Fixed #2511
|
* Fixed #2511
|
||||||
* Fixed #2636
|
* Fixed #2636
|
||||||
@ -54,6 +97,7 @@
|
|||||||
* Fixed #2760
|
* Fixed #2760
|
||||||
* Fixed #2771
|
* Fixed #2771
|
||||||
* Fixed placeholders that did not get loaded yet not having a label
|
* Fixed placeholders that did not get loaded yet not having a label
|
||||||
|
* Fixed #2679
|
||||||
|
|
||||||
## Release Candidate 19 (11 Jan 2021)
|
## Release Candidate 19 (11 Jan 2021)
|
||||||
|
|
||||||
@ -64,6 +108,7 @@
|
|||||||
#### Changes
|
#### Changes
|
||||||
* Performance optimizations for Cargo networks
|
* Performance optimizations for Cargo networks
|
||||||
* Removed an old version of bStats
|
* Removed an old version of bStats
|
||||||
|
* General performance improvements
|
||||||
* CraftBukkit is officially no longer supported, Slimefun will now be disabled on old builds of CraftBukkit
|
* CraftBukkit is officially no longer supported, Slimefun will now be disabled on old builds of CraftBukkit
|
||||||
* Removed the deprecated ItemManipulationAPI for BlockMenus
|
* Removed the deprecated ItemManipulationAPI for BlockMenus
|
||||||
* Removed the "Written Book" variant of the Slimefun Guide
|
* Removed the "Written Book" variant of the Slimefun Guide
|
||||||
|
@ -67,7 +67,7 @@ Well, we asked some users on our [Discord server](#discord) to send us some scre
|
|||||||
| *Screenshot provided by GalaxyKat11#3816* | *Screenshot provided by TamThan#7987* | *Screenshot provided by Kilaruna#4981* |
|
| *Screenshot provided by GalaxyKat11#3816* | *Screenshot provided by TamThan#7987* | *Screenshot provided by Kilaruna#4981* |
|
||||||
|
|
||||||
## Discord
|
## Discord
|
||||||
You can find Slimefun's community on Discord and connect with **over 3000** users of this plugin from all over the world.<br>
|
You can find Slimefun's community on Discord and connect with **over 4000** users of this plugin from all over the world.<br>
|
||||||
Click the badge down below to join the server for suggestions/questions or other discussions about this plugin.<br>
|
Click the badge down below to join the server for suggestions/questions or other discussions about this plugin.<br>
|
||||||
We are also hosting a community event every so often, join us to find out more.<br>
|
We are also hosting a community event every so often, join us to find out more.<br>
|
||||||
**Important**: We do **not** accept bug reports on discord, please use our [Issue Tracker](https://github.com/Slimefun/Slimefun4/issues) to submit bug reports!
|
**Important**: We do **not** accept bug reports on discord, please use our [Issue Tracker](https://github.com/Slimefun/Slimefun4/issues) to submit bug reports!
|
||||||
|
146
pom.xml
146
pom.xml
@ -18,7 +18,10 @@
|
|||||||
<url>https://github.com/Slimefun/Slimefun4</url>
|
<url>https://github.com/Slimefun/Slimefun4</url>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
|
<!-- UTF-8 is our standard encoding for source files -->
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
|
||||||
|
<!-- Target Java 8 -->
|
||||||
<maven.compiler.source>1.8</maven.compiler.source>
|
<maven.compiler.source>1.8</maven.compiler.source>
|
||||||
<maven.compiler.target>1.8</maven.compiler.target>
|
<maven.compiler.target>1.8</maven.compiler.target>
|
||||||
|
|
||||||
@ -34,68 +37,81 @@
|
|||||||
<sonar.coverage.jacoco.xmlReportPaths>target/site/jacoco/jacoco.xml</sonar.coverage.jacoco.xmlReportPaths>
|
<sonar.coverage.jacoco.xmlReportPaths>target/site/jacoco/jacoco.xml</sonar.coverage.jacoco.xmlReportPaths>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<!-- Bug Tracker -->
|
|
||||||
<issueManagement>
|
<issueManagement>
|
||||||
|
<!-- Bug Tracker -->
|
||||||
<system>GitHub Issues</system>
|
<system>GitHub Issues</system>
|
||||||
<url>https://github.com/Slimefun/Slimefun4/issues</url>
|
<url>https://github.com/Slimefun/Slimefun4/issues</url>
|
||||||
</issueManagement>
|
</issueManagement>
|
||||||
|
|
||||||
<!-- License -->
|
|
||||||
<licenses>
|
<licenses>
|
||||||
<license>
|
<license>
|
||||||
|
<!-- License -->
|
||||||
<name>GNU General Public License v3.0</name>
|
<name>GNU General Public License v3.0</name>
|
||||||
<url>https://github.com/Slimefun/Slimefun4/blob/master/LICENSE</url>
|
<url>https://github.com/Slimefun/Slimefun4/blob/master/LICENSE</url>
|
||||||
<distribution>repo</distribution>
|
<distribution>repo</distribution>
|
||||||
</license>
|
</license>
|
||||||
</licenses>
|
</licenses>
|
||||||
|
|
||||||
<!-- The repositories which host our dependencies -->
|
<!-- Repositories that host our dependencies -->
|
||||||
|
<!-- Well, any that aren't found on maven-central. -->
|
||||||
<repositories>
|
<repositories>
|
||||||
<repository>
|
<repository>
|
||||||
|
<!-- Spigot-API -->
|
||||||
<id>spigot-repo</id>
|
<id>spigot-repo</id>
|
||||||
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots</url>
|
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots</url>
|
||||||
</repository>
|
</repository>
|
||||||
<repository>
|
<repository>
|
||||||
|
<!-- PaperLib -->
|
||||||
<id>paper-repo</id>
|
<id>paper-repo</id>
|
||||||
<url>https://papermc.io/repo/repository/maven-public</url>
|
<url>https://papermc.io/repo/repository/maven-public</url>
|
||||||
</repository>
|
</repository>
|
||||||
<repository>
|
<repository>
|
||||||
|
<!-- CS-CoreLib2, ItemsAdder -->
|
||||||
<id>jitpack.io</id>
|
<id>jitpack.io</id>
|
||||||
<url>https://jitpack.io</url>
|
<url>https://jitpack.io</url>
|
||||||
</repository>
|
</repository>
|
||||||
<repository>
|
<repository>
|
||||||
|
<!-- WorldEdit -->
|
||||||
<id>worldedit-repo</id>
|
<id>worldedit-repo</id>
|
||||||
<url>https://maven.sk89q.com/repo</url>
|
<url>https://maven.sk89q.com/repo</url>
|
||||||
</repository>
|
</repository>
|
||||||
<repository>
|
<repository>
|
||||||
<id>codemc-repo</id>
|
<!-- PlaceholderAPI -->
|
||||||
<url>https://repo.codemc.org/repository/maven-public</url>
|
|
||||||
</repository>
|
|
||||||
<repository>
|
|
||||||
<id>placeholderapi-repo</id>
|
<id>placeholderapi-repo</id>
|
||||||
<url>https://repo.extendedclip.com/content/repositories/placeholderapi</url>
|
<url>https://repo.extendedclip.com/content/repositories/placeholderapi</url>
|
||||||
</repository>
|
</repository>
|
||||||
<repository>
|
<repository>
|
||||||
|
<!-- mcMMO -->
|
||||||
|
<id>mcmmo-repo</id>
|
||||||
|
<url>https://nexus.neetgames.com/repository/maven-public</url>
|
||||||
|
</repository>
|
||||||
|
<repository>
|
||||||
|
<!-- ClearLag -->
|
||||||
<id>walshy-public</id>
|
<id>walshy-public</id>
|
||||||
<url>https://repo.walshy.dev/public</url>
|
<url>https://repo.walshy.dev/public</url>
|
||||||
</repository>
|
</repository>
|
||||||
</repositories>
|
</repositories>
|
||||||
|
|
||||||
<!-- Build settings -->
|
|
||||||
<build>
|
<build>
|
||||||
|
<!-- /src/main/java/ contains all sources (production code) -->
|
||||||
<sourceDirectory>${project.basedir}/src/main/java</sourceDirectory>
|
<sourceDirectory>${project.basedir}/src/main/java</sourceDirectory>
|
||||||
|
|
||||||
|
<!-- /src/test/java/ contains all unit tests (testing code) -->
|
||||||
<testSourceDirectory>${project.basedir}/src/test/java</testSourceDirectory>
|
<testSourceDirectory>${project.basedir}/src/test/java</testSourceDirectory>
|
||||||
|
|
||||||
|
<!-- The default goal for compiling is "clean package" -->
|
||||||
<defaultGoal>clean package</defaultGoal>
|
<defaultGoal>clean package</defaultGoal>
|
||||||
|
|
||||||
<!-- The name of the final jar -->
|
<!-- The name of the final jar -->
|
||||||
<finalName>${project.name} v${project.version}</finalName>
|
<finalName>${project.name} v${project.version}</finalName>
|
||||||
|
|
||||||
<plugins>
|
<plugins>
|
||||||
<!-- Compiler plugin -->
|
|
||||||
<plugin>
|
<plugin>
|
||||||
|
<!-- Compiler plugin -->
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
<version>3.8.1</version>
|
<version>3.8.1</version>
|
||||||
|
|
||||||
<configuration>
|
<configuration>
|
||||||
<excludes>
|
<excludes>
|
||||||
<!-- package info files are only important for Javadocs -->
|
<!-- package info files are only important for Javadocs -->
|
||||||
@ -105,8 +121,8 @@
|
|||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
||||||
<!-- Attach sources -->
|
|
||||||
<plugin>
|
<plugin>
|
||||||
|
<!-- Attach sources -->
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-source-plugin</artifactId>
|
<artifactId>maven-source-plugin</artifactId>
|
||||||
<version>3.2.1</version>
|
<version>3.2.1</version>
|
||||||
@ -121,8 +137,8 @@
|
|||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
||||||
<!-- Plugin for Unit Tests -->
|
|
||||||
<plugin>
|
<plugin>
|
||||||
|
<!-- Plugin for Unit Tests -->
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-surefire-plugin</artifactId>
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
<version>3.0.0-M5</version>
|
<version>3.0.0-M5</version>
|
||||||
@ -133,15 +149,15 @@
|
|||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
||||||
<!-- Sonarcloud Scanner -->
|
|
||||||
<plugin>
|
<plugin>
|
||||||
|
<!-- Sonarcloud Scanner -->
|
||||||
<groupId>org.sonarsource.scanner.maven</groupId>
|
<groupId>org.sonarsource.scanner.maven</groupId>
|
||||||
<artifactId>sonar-maven-plugin</artifactId>
|
<artifactId>sonar-maven-plugin</artifactId>
|
||||||
<version>3.8.0.2131</version>
|
<version>3.8.0.2131</version>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
||||||
<!-- Code Coverage Reports -->
|
|
||||||
<plugin>
|
<plugin>
|
||||||
|
<!-- Code Coverage Reports -->
|
||||||
<groupId>org.jacoco</groupId>
|
<groupId>org.jacoco</groupId>
|
||||||
<artifactId>jacoco-maven-plugin</artifactId>
|
<artifactId>jacoco-maven-plugin</artifactId>
|
||||||
<version>0.8.6</version>
|
<version>0.8.6</version>
|
||||||
@ -166,8 +182,8 @@
|
|||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
||||||
<!-- Dependency shading -->
|
|
||||||
<plugin>
|
<plugin>
|
||||||
|
<!-- Dependency shading -->
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-shade-plugin</artifactId>
|
<artifactId>maven-shade-plugin</artifactId>
|
||||||
<version>3.2.4</version>
|
<version>3.2.4</version>
|
||||||
@ -210,8 +226,8 @@
|
|||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
||||||
<!-- Javadocs Settings -->
|
|
||||||
<plugin>
|
<plugin>
|
||||||
|
<!-- Javadocs -->
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-javadoc-plugin</artifactId>
|
<artifactId>maven-javadoc-plugin</artifactId>
|
||||||
<version>3.2.0</version>
|
<version>3.2.0</version>
|
||||||
@ -225,8 +241,8 @@
|
|||||||
<detectOfflineLinks>false</detectOfflineLinks>
|
<detectOfflineLinks>false</detectOfflineLinks>
|
||||||
<additionalJOption>-html5</additionalJOption>
|
<additionalJOption>-html5</additionalJOption>
|
||||||
|
|
||||||
<!-- We can reference the Spigot API in our Javadocs -->
|
|
||||||
<links>
|
<links>
|
||||||
|
<!-- We can reference the Spigot API in our Javadocs -->
|
||||||
<link>${spigot.javadocs}</link>
|
<link>${spigot.javadocs}</link>
|
||||||
</links>
|
</links>
|
||||||
|
|
||||||
@ -315,14 +331,21 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.junit.jupiter</groupId>
|
<groupId>org.junit.jupiter</groupId>
|
||||||
<artifactId>junit-jupiter</artifactId>
|
<artifactId>junit-jupiter</artifactId>
|
||||||
<version>5.7.0</version>
|
<version>5.7.1</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.mockito</groupId>
|
||||||
|
<artifactId>mockito-core</artifactId>
|
||||||
|
<version>3.8.0</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.github.seeseemelk</groupId>
|
<groupId>com.github.seeseemelk</groupId>
|
||||||
<artifactId>MockBukkit-v1.16</artifactId>
|
<artifactId>MockBukkit-v1.16</artifactId>
|
||||||
<version>0.21.0</version>
|
<version>0.31.0</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
|
|
||||||
<exclusions>
|
<exclusions>
|
||||||
<exclusion>
|
<exclusion>
|
||||||
<!-- We use javax.annotation instead. Excluding this -->
|
<!-- We use javax.annotation instead. Excluding this -->
|
||||||
@ -332,18 +355,12 @@
|
|||||||
</exclusion>
|
</exclusion>
|
||||||
</exclusions>
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.mockito</groupId>
|
|
||||||
<artifactId>mockito-core</artifactId>
|
|
||||||
<version>3.7.7</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- Shaded packages -->
|
<!-- Shaded packages -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.github.TheBusyBiscuit</groupId>
|
<groupId>com.github.TheBusyBiscuit</groupId>
|
||||||
<artifactId>CS-CoreLib2</artifactId>
|
<artifactId>CS-CoreLib2</artifactId>
|
||||||
<version>0.29.6</version>
|
<version>0.30.2</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
@ -355,10 +372,12 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.konghq</groupId>
|
<groupId>com.konghq</groupId>
|
||||||
<artifactId>unirest-java</artifactId>
|
<artifactId>unirest-java</artifactId>
|
||||||
<version>3.11.10</version>
|
<version>3.11.11</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
|
|
||||||
<exclusions>
|
<exclusions>
|
||||||
<exclusion>
|
<exclusion>
|
||||||
|
<!-- No need to shade Gson, Spigot does that already -->
|
||||||
<groupId>com.google.code.gson</groupId>
|
<groupId>com.google.code.gson</groupId>
|
||||||
<artifactId>gson</artifactId>
|
<artifactId>gson</artifactId>
|
||||||
</exclusion>
|
</exclusion>
|
||||||
@ -368,47 +387,42 @@
|
|||||||
<!-- Third party plugin integrations / soft dependencies -->
|
<!-- Third party plugin integrations / soft dependencies -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.sk89q.worldedit</groupId>
|
<groupId>com.sk89q.worldedit</groupId>
|
||||||
<artifactId>worldedit-bukkit</artifactId>
|
<artifactId>worldedit-core</artifactId>
|
||||||
<version>7.2.2</version>
|
<version>7.2.3</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
|
|
||||||
<exclusions>
|
<exclusions>
|
||||||
<exclusion>
|
<exclusion>
|
||||||
<!-- This one is ignored because it pops up everytime -->
|
<!-- We don't need any of the dependencies -->
|
||||||
<!-- I try to import File... yes, I want java.io.File -->
|
<groupId>*</groupId>
|
||||||
<groupId>de.schlichtherle</groupId>
|
<artifactId>*</artifactId>
|
||||||
<artifactId>truezip</artifactId>
|
|
||||||
</exclusion>
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.sk89q.worldedit</groupId>
|
||||||
|
<artifactId>worldedit-bukkit</artifactId>
|
||||||
|
<version>7.2.4</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
|
||||||
|
<exclusions>
|
||||||
<exclusion>
|
<exclusion>
|
||||||
<groupId>net.java.truevfs</groupId>
|
<!-- We don't need any of the dependencies -->
|
||||||
<artifactId>truevfs-profile-default_2.13</artifactId>
|
<groupId>*</groupId>
|
||||||
|
<artifactId>*</artifactId>
|
||||||
</exclusion>
|
</exclusion>
|
||||||
</exclusions>
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.gmail.nossr50.mcMMO</groupId>
|
<groupId>com.gmail.nossr50.mcMMO</groupId>
|
||||||
<artifactId>mcMMO</artifactId>
|
<artifactId>mcMMO</artifactId>
|
||||||
<version>2.1.173</version>
|
<version>2.1.181</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
|
|
||||||
<exclusions>
|
<exclusions>
|
||||||
<exclusion>
|
<exclusion>
|
||||||
<!-- We use javax.annotation instead. Excluding this -->
|
<!-- We don't need any of the dependencies -->
|
||||||
<!-- prevents us from using inconsistent annotations -->
|
<groupId>*</groupId>
|
||||||
<groupId>org.jetbrains</groupId>
|
|
||||||
<artifactId>annotations</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>com.sk89q.worldguard</groupId>
|
|
||||||
<artifactId>worldguard-core</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>com.sk89q.worldguard</groupId>
|
|
||||||
<artifactId>worldguard-legacy</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
<exclusion>
|
|
||||||
<!-- We do not want to use the wrong TextComponents by -->
|
|
||||||
<!-- accident. If we use adventure, then we will add -->
|
|
||||||
<!-- it ourselves. -->
|
|
||||||
<groupId>net.kyori</groupId>
|
|
||||||
<artifactId>*</artifactId>
|
<artifactId>*</artifactId>
|
||||||
</exclusion>
|
</exclusion>
|
||||||
</exclusions>
|
</exclusions>
|
||||||
@ -418,12 +432,12 @@
|
|||||||
<artifactId>placeholderapi</artifactId>
|
<artifactId>placeholderapi</artifactId>
|
||||||
<version>2.10.9</version>
|
<version>2.10.9</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
|
|
||||||
<exclusions>
|
<exclusions>
|
||||||
<exclusion>
|
<exclusion>
|
||||||
<!-- We use javax.annotation instead. Excluding this -->
|
<!-- We don't need any of the dependencies -->
|
||||||
<!-- prevents us from using inconsistent annotations -->
|
<groupId>*</groupId>
|
||||||
<groupId>org.jetbrains</groupId>
|
<artifactId>*</artifactId>
|
||||||
<artifactId>annotations</artifactId>
|
|
||||||
</exclusion>
|
</exclusion>
|
||||||
</exclusions>
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
@ -432,18 +446,26 @@
|
|||||||
<artifactId>clearlag-core</artifactId>
|
<artifactId>clearlag-core</artifactId>
|
||||||
<version>3.1.6</version>
|
<version>3.1.6</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
|
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<!-- We don't need any of the dependencies -->
|
||||||
|
<groupId>*</groupId>
|
||||||
|
<artifactId>*</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.github.LoneDev6</groupId>
|
<groupId>com.github.LoneDev6</groupId>
|
||||||
<artifactId>itemsadder-api</artifactId>
|
<artifactId>itemsadder-api</artifactId>
|
||||||
<version>2.1.25</version>
|
<version>2.2.1</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
|
|
||||||
<exclusions>
|
<exclusions>
|
||||||
<exclusion>
|
<exclusion>
|
||||||
<!-- We use javax.annotation instead. Excluding this -->
|
<!-- We don't need any of the dependencies -->
|
||||||
<!-- prevents us from using inconsistent annotations -->
|
<groupId>*</groupId>
|
||||||
<groupId>org.jetbrains</groupId>
|
<artifactId>*</artifactId>
|
||||||
<artifactId>annotations</artifactId>
|
|
||||||
</exclusion>
|
</exclusion>
|
||||||
</exclusions>
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
@ -7,7 +7,7 @@ import org.bukkit.event.Event;
|
|||||||
import org.bukkit.event.HandlerList;
|
import org.bukkit.event.HandlerList;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.AutoDisenchanter;
|
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.enchanting.AutoDisenchanter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An {@link Event} that is called whenever an {@link AutoDisenchanter} has
|
* An {@link Event} that is called whenever an {@link AutoDisenchanter} has
|
||||||
|
@ -0,0 +1,95 @@
|
|||||||
|
package io.github.thebusybiscuit.slimefun4.api.events;
|
||||||
|
|
||||||
|
import io.github.thebusybiscuit.slimefun4.implementation.items.tools.ExplosiveTool;
|
||||||
|
import org.apache.commons.lang.Validate;
|
||||||
|
import org.bukkit.block.Block;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.Cancellable;
|
||||||
|
import org.bukkit.event.Event;
|
||||||
|
import org.bukkit.event.HandlerList;
|
||||||
|
import org.bukkit.event.player.PlayerEvent;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This {@link Event} is called when an {@link ExplosiveTool} is used to break blocks.
|
||||||
|
*
|
||||||
|
* @author GallowsDove
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ExplosiveToolBreakBlocksEvent extends PlayerEvent implements Cancellable {
|
||||||
|
|
||||||
|
private static final HandlerList handlers = new HandlerList();
|
||||||
|
|
||||||
|
private final ItemStack itemInHand;
|
||||||
|
private final ExplosiveTool explosiveTool;
|
||||||
|
private final List<Block> blocks;
|
||||||
|
private boolean cancelled;
|
||||||
|
|
||||||
|
@ParametersAreNonnullByDefault
|
||||||
|
public ExplosiveToolBreakBlocksEvent(Player player, List<Block> blocks, ItemStack item, ExplosiveTool explosiveTool) {
|
||||||
|
super(player);
|
||||||
|
|
||||||
|
Validate.notEmpty(blocks, "Blocks cannot be null or empty");
|
||||||
|
Validate.notNull(item, "Item cannot be null");
|
||||||
|
Validate.notNull(explosiveTool, "ExplosiveTool cannot be null");
|
||||||
|
|
||||||
|
this.blocks = blocks;
|
||||||
|
this.itemInHand = item;
|
||||||
|
this.explosiveTool = explosiveTool;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the {@link Block} {@link List} of blocks destroyed in this event.
|
||||||
|
*
|
||||||
|
* @return The broken blocks
|
||||||
|
*/
|
||||||
|
@Nonnull
|
||||||
|
public List<Block> getBlocks() {
|
||||||
|
return this.blocks;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the {@link ExplosiveTool} which triggered this event
|
||||||
|
*
|
||||||
|
* @return the {@link ExplosiveTool} that was involved
|
||||||
|
*/
|
||||||
|
@Nonnull
|
||||||
|
public ExplosiveTool getExplosiveTool() {
|
||||||
|
return this.explosiveTool;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the {@link ItemStack} of the tool used to destroy this block
|
||||||
|
*
|
||||||
|
* @return The {@link ItemStack} in the hand of the {@link Player}
|
||||||
|
*/
|
||||||
|
@Nonnull
|
||||||
|
public ItemStack getItemInHand() {
|
||||||
|
return this.itemInHand;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCancelled() {
|
||||||
|
return cancelled;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setCancelled(boolean cancel) {
|
||||||
|
this.cancelled = cancel;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
public static HandlerList getHandlerList() {
|
||||||
|
return handlers;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
public HandlerList getHandlers() {
|
||||||
|
return getHandlerList();
|
||||||
|
}
|
||||||
|
}
|
@ -79,6 +79,7 @@ public abstract class Network {
|
|||||||
*
|
*
|
||||||
* @param l
|
* @param l
|
||||||
* The {@link Location} to classify
|
* The {@link Location} to classify
|
||||||
|
*
|
||||||
* @return The assigned type of {@link NetworkComponent} for this {@link Location}
|
* @return The assigned type of {@link NetworkComponent} for this {@link Location}
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
|
@ -64,12 +64,14 @@ public final class SlimefunRegistry {
|
|||||||
private final List<String> researchRanks = new ArrayList<>();
|
private final List<String> researchRanks = new ArrayList<>();
|
||||||
private final Set<UUID> researchingPlayers = Collections.synchronizedSet(new HashSet<>());
|
private final Set<UUID> researchingPlayers = Collections.synchronizedSet(new HashSet<>());
|
||||||
|
|
||||||
|
// TODO: Move this all into a proper "config cache" class
|
||||||
private boolean backwardsCompatibility;
|
private boolean backwardsCompatibility;
|
||||||
private boolean automaticallyLoadItems;
|
private boolean automaticallyLoadItems;
|
||||||
private boolean enableResearches;
|
private boolean enableResearches;
|
||||||
private boolean freeCreativeResearches;
|
private boolean freeCreativeResearches;
|
||||||
private boolean researchFireworks;
|
private boolean researchFireworks;
|
||||||
private boolean logDuplicateBlockEntries;
|
private boolean logDuplicateBlockEntries;
|
||||||
|
private boolean talismanActionBarMessages;
|
||||||
|
|
||||||
private final Set<String> tickers = new HashSet<>();
|
private final Set<String> tickers = new HashSet<>();
|
||||||
private final Set<SlimefunItem> radioactive = new HashSet<>();
|
private final Set<SlimefunItem> radioactive = new HashSet<>();
|
||||||
@ -110,6 +112,7 @@ public final class SlimefunRegistry {
|
|||||||
freeCreativeResearches = cfg.getBoolean("researches.free-in-creative-mode");
|
freeCreativeResearches = cfg.getBoolean("researches.free-in-creative-mode");
|
||||||
researchFireworks = cfg.getBoolean("researches.enable-fireworks");
|
researchFireworks = cfg.getBoolean("researches.enable-fireworks");
|
||||||
logDuplicateBlockEntries = cfg.getBoolean("options.log-duplicate-block-entries");
|
logDuplicateBlockEntries = cfg.getBoolean("options.log-duplicate-block-entries");
|
||||||
|
talismanActionBarMessages = cfg.getBoolean("talismans.use-actionbar");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -330,6 +333,7 @@ public final class SlimefunRegistry {
|
|||||||
return globalItemHandlers;
|
return globalItemHandlers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public Map<String, SlimefunBlockHandler> getBlockHandlers() {
|
public Map<String, SlimefunBlockHandler> getBlockHandlers() {
|
||||||
return blockHandlers;
|
return blockHandlers;
|
||||||
@ -354,6 +358,10 @@ public final class SlimefunRegistry {
|
|||||||
return logDuplicateBlockEntries;
|
return logDuplicateBlockEntries;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean useActionbarForTalismans() {
|
||||||
|
return talismanActionBarMessages;
|
||||||
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public NamespacedKey getSoulboundDataKey() {
|
public NamespacedKey getSoulboundDataKey() {
|
||||||
return soulboundKey;
|
return soulboundKey;
|
||||||
|
@ -19,7 +19,6 @@ import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile;
|
|||||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||||
import me.mrCookieSlime.Slimefun.Objects.Category;
|
import me.mrCookieSlime.Slimefun.Objects.Category;
|
||||||
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
|
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
|
||||||
import me.mrCookieSlime.Slimefun.api.Slimefun;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a {@link Category} that cannot be opened until the parent category/categories
|
* Represents a {@link Category} that cannot be opened until the parent category/categories
|
||||||
@ -153,14 +152,13 @@ public class LockedCategory extends Category {
|
|||||||
* @return Whether the {@link Player} has fully completed all parent categories, otherwise false
|
* @return Whether the {@link Player} has fully completed all parent categories, otherwise false
|
||||||
*/
|
*/
|
||||||
public boolean hasUnlocked(@Nonnull Player p, @Nonnull PlayerProfile profile) {
|
public boolean hasUnlocked(@Nonnull Player p, @Nonnull PlayerProfile profile) {
|
||||||
|
Validate.notNull(p, "The player cannot be null!");
|
||||||
|
Validate.notNull(profile, "The Profile cannot be null!");
|
||||||
|
|
||||||
for (Category category : parents) {
|
for (Category category : parents) {
|
||||||
for (SlimefunItem item : category.getItems()) {
|
for (SlimefunItem item : category.getItems()) {
|
||||||
/*
|
// Check if the Player has researched every item (if the item is enabled)
|
||||||
* Should probably be replaced with Slimefun.hasUnlocked(...)
|
if (!item.isDisabledIn(p.getWorld()) && item.hasResearch() && !profile.hasUnlocked(item.getResearch())) {
|
||||||
* However this will result in better performance because we don't
|
|
||||||
* request the PlayerProfile everytime
|
|
||||||
*/
|
|
||||||
if (Slimefun.isEnabled(p, item, false) && Slimefun.hasPermission(p, item, false) && !profile.hasUnlocked(item.getResearch())) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,138 @@
|
|||||||
|
package io.github.thebusybiscuit.slimefun4.core.categories;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
|
|
||||||
|
import org.apache.commons.lang.Validate;
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
|
import org.bukkit.NamespacedKey;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
|
||||||
|
import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile;
|
||||||
|
import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuide;
|
||||||
|
import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideMode;
|
||||||
|
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||||
|
import io.github.thebusybiscuit.slimefun4.implementation.guide.SurvivalSlimefunGuide;
|
||||||
|
import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils;
|
||||||
|
import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu;
|
||||||
|
|
||||||
|
public class MultiCategory extends FlexCategory {
|
||||||
|
|
||||||
|
private static final int CATEGORY_SIZE = 36;
|
||||||
|
private final List<SubCategory> subCategories = new ArrayList<>();
|
||||||
|
|
||||||
|
@ParametersAreNonnullByDefault
|
||||||
|
public MultiCategory(NamespacedKey key, ItemStack item) {
|
||||||
|
this(key, item, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParametersAreNonnullByDefault
|
||||||
|
public MultiCategory(NamespacedKey key, ItemStack item, int tier) {
|
||||||
|
super(key, item, tier);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This will add the given {@link SubCategory} to this {@link MultiCategory}.
|
||||||
|
*
|
||||||
|
* @param category
|
||||||
|
* The {@link SubCategory} to add.
|
||||||
|
*/
|
||||||
|
public void addSubCategory(@Nonnull SubCategory category) {
|
||||||
|
Validate.notNull(category, "The Category cannot be null!");
|
||||||
|
|
||||||
|
subCategories.add(category);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This will remove the given {@link SubCategory} from this {@link MultiCategory} (if present).
|
||||||
|
*
|
||||||
|
* @param category
|
||||||
|
* The {@link SubCategory} to remove.
|
||||||
|
*/
|
||||||
|
public void removeSubCategory(@Nonnull SubCategory category) {
|
||||||
|
Validate.notNull(category, "The Category cannot be null!");
|
||||||
|
|
||||||
|
subCategories.remove(category);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@ParametersAreNonnullByDefault
|
||||||
|
public boolean isVisible(Player p, PlayerProfile profile, SlimefunGuideMode mode) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@ParametersAreNonnullByDefault
|
||||||
|
public void open(Player p, PlayerProfile profile, SlimefunGuideMode mode) {
|
||||||
|
openGuide(p, profile, mode, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParametersAreNonnullByDefault
|
||||||
|
private void openGuide(Player p, PlayerProfile profile, SlimefunGuideMode mode, int page) {
|
||||||
|
if (mode == SlimefunGuideMode.SURVIVAL_MODE) {
|
||||||
|
profile.getGuideHistory().add(this, page);
|
||||||
|
}
|
||||||
|
|
||||||
|
ChestMenu menu = new ChestMenu(SlimefunPlugin.getLocalization().getMessage(p, "guide.title.main"));
|
||||||
|
SurvivalSlimefunGuide guide = (SurvivalSlimefunGuide) SlimefunPlugin.getRegistry().getSlimefunGuide(mode);
|
||||||
|
|
||||||
|
menu.setEmptySlotsClickable(false);
|
||||||
|
menu.addMenuOpeningHandler(pl -> pl.playSound(pl.getLocation(), guide.getSound(), 1, 1));
|
||||||
|
guide.createHeader(p, profile, menu);
|
||||||
|
|
||||||
|
menu.addItem(1, new CustomItem(ChestMenuUtils.getBackButton(p, "", ChatColor.GRAY + SlimefunPlugin.getLocalization().getMessage(p, "guide.back.guide"))));
|
||||||
|
menu.addMenuClickHandler(1, (pl, s, is, action) -> {
|
||||||
|
SlimefunGuide.openMainMenu(profile, mode, 1);
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
int index = 9;
|
||||||
|
|
||||||
|
int target = (CATEGORY_SIZE * (page - 1)) - 1;
|
||||||
|
|
||||||
|
while (target < (subCategories.size() - 1) && index < CATEGORY_SIZE + 9) {
|
||||||
|
target++;
|
||||||
|
|
||||||
|
SubCategory category = subCategories.get(target);
|
||||||
|
menu.addItem(index, category.getItem(p));
|
||||||
|
menu.addMenuClickHandler(index, (pl, slot, item, action) -> {
|
||||||
|
SlimefunGuide.openCategory(profile, category, mode, 1);
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
int pages = target == subCategories.size() - 1 ? page : (subCategories.size() - 1) / CATEGORY_SIZE + 1;
|
||||||
|
|
||||||
|
menu.addItem(46, ChestMenuUtils.getPreviousButton(p, page, pages));
|
||||||
|
menu.addMenuClickHandler(46, (pl, slot, item, action) -> {
|
||||||
|
int next = page - 1;
|
||||||
|
|
||||||
|
if (next != page && next > 0) {
|
||||||
|
openGuide(p, profile, mode, next);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
menu.addItem(52, ChestMenuUtils.getNextButton(p, page, pages));
|
||||||
|
menu.addMenuClickHandler(52, (pl, slot, item, action) -> {
|
||||||
|
int next = page + 1;
|
||||||
|
|
||||||
|
if (next != page && next <= pages) {
|
||||||
|
openGuide(p, profile, mode, next);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
menu.open(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,65 @@
|
|||||||
|
package io.github.thebusybiscuit.slimefun4.core.categories;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
|
|
||||||
|
import org.apache.commons.lang.Validate;
|
||||||
|
import org.bukkit.NamespacedKey;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
import io.github.thebusybiscuit.slimefun4.api.SlimefunAddon;
|
||||||
|
import me.mrCookieSlime.Slimefun.Objects.Category;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link SubCategory} is a child {@link Category} of the
|
||||||
|
* {@link MultiCategory}.
|
||||||
|
*
|
||||||
|
* @author TheBusyBiscuit
|
||||||
|
*
|
||||||
|
* @see MultiCategory
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class SubCategory extends Category {
|
||||||
|
|
||||||
|
private final MultiCategory multiCategory;
|
||||||
|
|
||||||
|
@ParametersAreNonnullByDefault
|
||||||
|
public SubCategory(NamespacedKey key, MultiCategory parent, ItemStack item) {
|
||||||
|
this(key, parent, item, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParametersAreNonnullByDefault
|
||||||
|
public SubCategory(NamespacedKey key, MultiCategory parent, ItemStack item, int tier) {
|
||||||
|
super(key, item, tier);
|
||||||
|
|
||||||
|
Validate.notNull(parent, "The parent category cannot be null");
|
||||||
|
|
||||||
|
multiCategory = parent;
|
||||||
|
parent.addSubCategory(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final boolean isHidden(@Nonnull Player p) {
|
||||||
|
/*
|
||||||
|
* Sub Categories are always hidden,
|
||||||
|
* they won't show up in the normal guide view.
|
||||||
|
*/
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
public final MultiCategory getParent() {
|
||||||
|
return multiCategory;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void register(@Nonnull SlimefunAddon addon) {
|
||||||
|
super.register(addon);
|
||||||
|
|
||||||
|
if (!multiCategory.isRegistered()) {
|
||||||
|
multiCategory.register(addon);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -3,18 +3,30 @@ package io.github.thebusybiscuit.slimefun4.core.commands.subcommands;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.ChatColor;
|
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.command.ConsoleCommandSender;
|
import org.bukkit.command.ConsoleCommandSender;
|
||||||
import org.bukkit.plugin.Plugin;
|
import org.bukkit.plugin.Plugin;
|
||||||
|
|
||||||
import io.github.thebusybiscuit.cscorelib2.chat.ChatColors;
|
import io.github.thebusybiscuit.slimefun4.api.SlimefunAddon;
|
||||||
import io.github.thebusybiscuit.slimefun4.core.commands.SlimefunCommand;
|
import io.github.thebusybiscuit.slimefun4.core.commands.SlimefunCommand;
|
||||||
import io.github.thebusybiscuit.slimefun4.core.commands.SubCommand;
|
import io.github.thebusybiscuit.slimefun4.core.commands.SubCommand;
|
||||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||||
import io.papermc.lib.PaperLib;
|
import io.papermc.lib.PaperLib;
|
||||||
|
import net.md_5.bungee.api.ChatColor;
|
||||||
|
import net.md_5.bungee.api.chat.ClickEvent;
|
||||||
|
import net.md_5.bungee.api.chat.ComponentBuilder;
|
||||||
|
import net.md_5.bungee.api.chat.HoverEvent;
|
||||||
|
import net.md_5.bungee.api.chat.hover.content.Text;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is our class for the /sf versions subcommand.
|
||||||
|
*
|
||||||
|
* @author TheBusyBiscuit
|
||||||
|
* @author Walshy
|
||||||
|
*
|
||||||
|
*/
|
||||||
class VersionsCommand extends SubCommand {
|
class VersionsCommand extends SubCommand {
|
||||||
|
|
||||||
VersionsCommand(SlimefunPlugin plugin, SlimefunCommand cmd) {
|
VersionsCommand(SlimefunPlugin plugin, SlimefunCommand cmd) {
|
||||||
@ -24,39 +36,171 @@ class VersionsCommand extends SubCommand {
|
|||||||
@Override
|
@Override
|
||||||
public void onExecute(@Nonnull CommandSender sender, @Nonnull String[] args) {
|
public void onExecute(@Nonnull CommandSender sender, @Nonnull String[] args) {
|
||||||
if (sender.hasPermission("slimefun.command.versions") || sender instanceof ConsoleCommandSender) {
|
if (sender.hasPermission("slimefun.command.versions") || sender instanceof ConsoleCommandSender) {
|
||||||
// After all these years... Spigot still displays as "CraftBukkit"
|
/*
|
||||||
// so we will just fix this inconsistency for them :)
|
* 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();
|
String serverSoftware = PaperLib.isSpigot() && !PaperLib.isPaper() ? "Spigot" : Bukkit.getName();
|
||||||
|
ComponentBuilder builder = new ComponentBuilder();
|
||||||
|
|
||||||
sender.sendMessage(ChatColor.GRAY + "This Server uses the following setup of Slimefun:");
|
// @formatter:off
|
||||||
sender.sendMessage(ChatColors.color("&a" + serverSoftware + " &2" + Bukkit.getVersion()));
|
builder.append("This Server uses the following setup of Slimefun:\n")
|
||||||
sender.sendMessage(ChatColors.color("&aSlimefun &2v" + SlimefunPlugin.getVersion()));
|
.color(ChatColor.GRAY)
|
||||||
|
.append(serverSoftware)
|
||||||
|
.color(ChatColor.GREEN)
|
||||||
|
.append(" " + Bukkit.getVersion() + '\n')
|
||||||
|
.color(ChatColor.DARK_GREEN)
|
||||||
|
.append("Slimefun ")
|
||||||
|
.color(ChatColor.GREEN)
|
||||||
|
.append(SlimefunPlugin.getVersion() + '\n')
|
||||||
|
.color(ChatColor.DARK_GREEN);
|
||||||
|
// @formatter:on
|
||||||
|
|
||||||
if (SlimefunPlugin.getMetricsService().getVersion() != null) {
|
if (SlimefunPlugin.getMetricsService().getVersion() != null) {
|
||||||
sender.sendMessage(ChatColors.color("&aMetrics build: &2#" + SlimefunPlugin.getMetricsService().getVersion()));
|
// @formatter:off
|
||||||
|
builder.append("Metrics-Module ")
|
||||||
|
.color(ChatColor.GREEN)
|
||||||
|
.append("#" + SlimefunPlugin.getMetricsService().getVersion() + '\n')
|
||||||
|
.color(ChatColor.DARK_GREEN);
|
||||||
|
// @formatter:on
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addJavaVersion(builder);
|
||||||
|
|
||||||
if (SlimefunPlugin.getRegistry().isBackwardsCompatible()) {
|
if (SlimefunPlugin.getRegistry().isBackwardsCompatible()) {
|
||||||
sender.sendMessage(ChatColor.RED + "Backwards compatibility enabled!");
|
// @formatter:off
|
||||||
|
HoverEvent hoverEvent = new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text(
|
||||||
|
"Backwards compatibility has a negative impact on performance!\n" +
|
||||||
|
"We recommend you to disable this setting unless your server still " +
|
||||||
|
"has legacy Slimefun items (from before summer 2019) in circulation."
|
||||||
|
));
|
||||||
|
// @formatter:on
|
||||||
|
|
||||||
|
builder.append("\nBackwards compatibility enabled!\n").color(ChatColor.RED).event(hoverEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
sender.sendMessage("");
|
builder.append("\n").event((HoverEvent) null);
|
||||||
|
addPluginVersions(builder);
|
||||||
|
|
||||||
Collection<Plugin> addons = SlimefunPlugin.getInstalledAddons();
|
sender.spigot().sendMessage(builder.create());
|
||||||
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(ChatColor.GREEN + " " + plugin.getName() + ChatColor.DARK_GREEN + " v" + version);
|
|
||||||
} else {
|
|
||||||
sender.sendMessage(ChatColor.RED + " " + plugin.getName() + ChatColor.DARK_RED + " v" + version);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
SlimefunPlugin.getLocalization().sendMessage(sender, "messages.no-permission", true);
|
SlimefunPlugin.getLocalization().sendMessage(sender, "messages.no-permission", true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void addJavaVersion(@Nonnull ComponentBuilder builder) {
|
||||||
|
String javaVer = System.getProperty("java.version");
|
||||||
|
|
||||||
|
if (javaVer.startsWith("1.")) {
|
||||||
|
javaVer = javaVer.substring(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If it's like 11.0.1.3 or 8.0_275
|
||||||
|
if (javaVer.indexOf('.') != -1) {
|
||||||
|
javaVer = javaVer.substring(0, javaVer.indexOf('.'));
|
||||||
|
}
|
||||||
|
|
||||||
|
int version = Integer.parseInt(javaVer);
|
||||||
|
|
||||||
|
if (version < 11) {
|
||||||
|
// @formatter:off
|
||||||
|
builder.append("Java " + version).color(ChatColor.RED)
|
||||||
|
.event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text(
|
||||||
|
"Your Java version is out of date!\n!" +
|
||||||
|
"You should use Java 11 or higher.\n" +
|
||||||
|
"Paper will be dropping support for older versions with the release of Minecraft 1.17."
|
||||||
|
)))
|
||||||
|
.append("\n")
|
||||||
|
.event((HoverEvent) null);
|
||||||
|
// @formatter:on
|
||||||
|
} else {
|
||||||
|
builder.append("Java ").color(ChatColor.GREEN).append(version + "\n").color(ChatColor.DARK_GREEN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addPluginVersions(@Nonnull ComponentBuilder builder) {
|
||||||
|
Collection<Plugin> addons = SlimefunPlugin.getInstalledAddons();
|
||||||
|
|
||||||
|
if (addons.isEmpty()) {
|
||||||
|
builder.append("No Addons installed").color(ChatColor.GRAY).italic(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.append("Installed Addons: ").color(ChatColor.GRAY).append("(" + addons.size() + ")").color(ChatColor.DARK_GRAY);
|
||||||
|
|
||||||
|
for (Plugin plugin : addons) {
|
||||||
|
String version = plugin.getDescription().getVersion();
|
||||||
|
|
||||||
|
HoverEvent hoverEvent = null;
|
||||||
|
ClickEvent clickEvent = null;
|
||||||
|
ChatColor primaryColor;
|
||||||
|
ChatColor secondaryColor;
|
||||||
|
|
||||||
|
if (Bukkit.getPluginManager().isPluginEnabled(plugin)) {
|
||||||
|
primaryColor = ChatColor.GREEN;
|
||||||
|
secondaryColor = ChatColor.DARK_GREEN;
|
||||||
|
String authors = String.join(", ", plugin.getDescription().getAuthors());
|
||||||
|
|
||||||
|
if (plugin instanceof SlimefunAddon && ((SlimefunAddon) plugin).getBugTrackerURL() != null) {
|
||||||
|
// @formatter:off
|
||||||
|
hoverEvent = new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text(new ComponentBuilder()
|
||||||
|
.append("Author(s): ")
|
||||||
|
.append(authors)
|
||||||
|
.color(ChatColor.YELLOW)
|
||||||
|
.append("\n> Click here to go to their issues tracker")
|
||||||
|
.color(ChatColor.GOLD)
|
||||||
|
.create()
|
||||||
|
));
|
||||||
|
// @formatter:on
|
||||||
|
|
||||||
|
clickEvent = new ClickEvent(ClickEvent.Action.OPEN_URL, ((SlimefunAddon) plugin).getBugTrackerURL());
|
||||||
|
} else {
|
||||||
|
// @formatter:off
|
||||||
|
hoverEvent = new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text(new ComponentBuilder()
|
||||||
|
.append("Author(s): ")
|
||||||
|
.append(authors)
|
||||||
|
.color(ChatColor.YELLOW)
|
||||||
|
.create()
|
||||||
|
));
|
||||||
|
// @formatter:on
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
primaryColor = ChatColor.RED;
|
||||||
|
secondaryColor = ChatColor.DARK_RED;
|
||||||
|
|
||||||
|
if (plugin instanceof SlimefunAddon && ((SlimefunAddon) plugin).getBugTrackerURL() != null) {
|
||||||
|
// @formatter:off
|
||||||
|
hoverEvent = new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text(new ComponentBuilder()
|
||||||
|
.append("This plugin is disabled.\nCheck the console for an error message.")
|
||||||
|
.color(ChatColor.RED)
|
||||||
|
.append("\n> Click here to report on their issues tracker")
|
||||||
|
.color(ChatColor.DARK_RED)
|
||||||
|
.create()
|
||||||
|
));
|
||||||
|
// @formatter:on
|
||||||
|
|
||||||
|
SlimefunAddon addon = (SlimefunAddon) plugin;
|
||||||
|
|
||||||
|
if (addon.getBugTrackerURL() != null) {
|
||||||
|
clickEvent = new ClickEvent(ClickEvent.Action.OPEN_URL, addon.getBugTrackerURL());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
hoverEvent = new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text("Plugin is disabled. Check the console for an error and report on their issues tracker."));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// @formatter:off
|
||||||
|
// We need to reset the hover event or it's added to all components
|
||||||
|
builder.append("\n " + plugin.getName())
|
||||||
|
.color(primaryColor)
|
||||||
|
.event(hoverEvent)
|
||||||
|
.event(clickEvent)
|
||||||
|
.append(" v" + version)
|
||||||
|
.color(secondaryColor)
|
||||||
|
.append("")
|
||||||
|
.event((ClickEvent) null)
|
||||||
|
.event((HoverEvent) null);
|
||||||
|
// @formatter:on
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,18 +2,103 @@ package io.github.thebusybiscuit.slimefun4.core.handlers;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
|
|
||||||
|
import org.bukkit.block.Block;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.block.BlockBreakEvent;
|
import org.bukkit.event.block.BlockBreakEvent;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
import io.github.thebusybiscuit.slimefun4.api.events.AndroidMineEvent;
|
||||||
|
import io.github.thebusybiscuit.slimefun4.implementation.items.androids.MinerAndroid;
|
||||||
|
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
|
||||||
import me.mrCookieSlime.Slimefun.Objects.handlers.ItemHandler;
|
import me.mrCookieSlime.Slimefun.Objects.handlers.ItemHandler;
|
||||||
|
|
||||||
@FunctionalInterface
|
/**
|
||||||
public interface BlockBreakHandler extends ItemHandler {
|
* The {@link BlockBreakHandler} is called when a {@link Block} is broken
|
||||||
|
* which holds a {@link SlimefunItem}.
|
||||||
|
* The {@link BlockBreakHandler} provides three methods for this, one for block breaking
|
||||||
|
* caused by a {@link Player}, one for a {@link MinerAndroid} and one method for a {@link Block}
|
||||||
|
* being destroyed by an explosion.
|
||||||
|
*
|
||||||
|
* @author TheBusyBiscuit
|
||||||
|
*
|
||||||
|
* @see BlockPlaceHandler
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public abstract class BlockBreakHandler implements ItemHandler {
|
||||||
|
|
||||||
boolean onBlockBreak(BlockBreakEvent e, ItemStack item, int fortune, List<ItemStack> drops);
|
/**
|
||||||
|
* Whether a {@link MinerAndroid} is allowed to break this block.
|
||||||
|
*/
|
||||||
|
private final boolean allowAndroids;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether an explosion is allowed to destroy this block.
|
||||||
|
*/
|
||||||
|
private final boolean allowExplosions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This constructs a new {@link BlockBreakHandler}.
|
||||||
|
*
|
||||||
|
* @param allowAndroids
|
||||||
|
* Whether a {@link MinerAndroid} is allowed to break blocks of this type
|
||||||
|
* @param allowExplosions
|
||||||
|
* Whether blocks of this type are allowed to be broken by explosions
|
||||||
|
*/
|
||||||
|
public BlockBreakHandler(boolean allowAndroids, boolean allowExplosions) {
|
||||||
|
this.allowAndroids = allowAndroids;
|
||||||
|
this.allowExplosions = allowExplosions;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParametersAreNonnullByDefault
|
||||||
|
public abstract void onPlayerBreak(BlockBreakEvent e, ItemStack item, List<ItemStack> drops);
|
||||||
|
|
||||||
|
@ParametersAreNonnullByDefault
|
||||||
|
public void onExplode(Block b, List<ItemStack> drops) {
|
||||||
|
// This can be overridden, if necessary
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParametersAreNonnullByDefault
|
||||||
|
public void onAndroidBreak(AndroidMineEvent e) {
|
||||||
|
// This can be overridden, if necessary
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This returns whether an explosion is able to break the given {@link Block}.
|
||||||
|
*
|
||||||
|
* @param b
|
||||||
|
* The {@link Block}
|
||||||
|
* @return Whether explosions can destroy this {@link Block}
|
||||||
|
*/
|
||||||
|
public boolean isExplosionAllowed(@Nonnull Block b) {
|
||||||
|
/*
|
||||||
|
* By default our flag is returned, but you can override it
|
||||||
|
* to be handled on a per-Block basis.
|
||||||
|
*/
|
||||||
|
return allowExplosions;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This returns whether a {@link MinerAndroid} is allowed to break
|
||||||
|
* the given {@link Block}.
|
||||||
|
*
|
||||||
|
* @param b
|
||||||
|
* The {@link Block}
|
||||||
|
*
|
||||||
|
* @return Whether androids can break the given {@link Block}
|
||||||
|
*/
|
||||||
|
public boolean isAndroidAllowed(@Nonnull Block b) {
|
||||||
|
/*
|
||||||
|
* By default our flag is returned, but you can override it
|
||||||
|
* to be handled on a per-Block basis.
|
||||||
|
*/
|
||||||
|
return allowAndroids;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
default Class<? extends ItemHandler> getIdentifier() {
|
public final Class<? extends ItemHandler> getIdentifier() {
|
||||||
return BlockBreakHandler.class;
|
return BlockBreakHandler.class;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package io.github.thebusybiscuit.slimefun4.core.handlers;
|
package io.github.thebusybiscuit.slimefun4.core.handlers;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.block.BlockPlaceEvent;
|
import org.bukkit.event.block.BlockPlaceEvent;
|
||||||
@ -31,7 +33,7 @@ public abstract class BlockPlaceHandler implements ItemHandler {
|
|||||||
* @param e
|
* @param e
|
||||||
* The corresponding {@link BlockPlaceEvent}
|
* The corresponding {@link BlockPlaceEvent}
|
||||||
*/
|
*/
|
||||||
public abstract void onPlayerPlace(BlockPlaceEvent e);
|
public abstract void onPlayerPlace(@Nonnull BlockPlaceEvent e);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is called whenever a {@link BlockPlacer} places this {@link Block}.
|
* This method is called whenever a {@link BlockPlacer} places this {@link Block}.
|
||||||
@ -42,7 +44,7 @@ public abstract class BlockPlaceHandler implements ItemHandler {
|
|||||||
* @param e
|
* @param e
|
||||||
* The corresponding {@link BlockPlacerPlaceEvent}
|
* The corresponding {@link BlockPlacerPlaceEvent}
|
||||||
*/
|
*/
|
||||||
public void onBlockPlacerPlace(BlockPlacerPlaceEvent e) {
|
public void onBlockPlacerPlace(@Nonnull BlockPlacerPlaceEvent e) {
|
||||||
// This can be overridden, if necessary
|
// This can be overridden, if necessary
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,7 +58,7 @@ public abstract class BlockPlaceHandler implements ItemHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Class<? extends ItemHandler> getIdentifier() {
|
public final Class<? extends ItemHandler> getIdentifier() {
|
||||||
return BlockPlaceHandler.class;
|
return BlockPlaceHandler.class;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ import java.util.List;
|
|||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
|
|
||||||
import org.apache.commons.lang.Validate;
|
import org.apache.commons.lang.Validate;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
@ -26,12 +27,12 @@ import io.github.thebusybiscuit.slimefun4.core.attributes.NotPlaceable;
|
|||||||
import io.github.thebusybiscuit.slimefun4.core.attributes.RecipeDisplayItem;
|
import io.github.thebusybiscuit.slimefun4.core.attributes.RecipeDisplayItem;
|
||||||
import io.github.thebusybiscuit.slimefun4.core.handlers.MultiBlockInteractionHandler;
|
import io.github.thebusybiscuit.slimefun4.core.handlers.MultiBlockInteractionHandler;
|
||||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||||
|
import io.github.thebusybiscuit.slimefun4.implementation.items.blocks.OutputChest;
|
||||||
import io.papermc.lib.PaperLib;
|
import io.papermc.lib.PaperLib;
|
||||||
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
|
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
|
||||||
import me.mrCookieSlime.Slimefun.Objects.Category;
|
import me.mrCookieSlime.Slimefun.Objects.Category;
|
||||||
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
|
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
|
||||||
import me.mrCookieSlime.Slimefun.api.BlockStorage;
|
import me.mrCookieSlime.Slimefun.api.BlockStorage;
|
||||||
import me.mrCookieSlime.Slimefun.api.Slimefun;
|
|
||||||
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -51,6 +52,7 @@ public abstract class MultiBlockMachine extends SlimefunItem implements NotPlace
|
|||||||
protected final List<ItemStack> displayRecipes;
|
protected final List<ItemStack> displayRecipes;
|
||||||
protected final MultiBlock multiblock;
|
protected final MultiBlock multiblock;
|
||||||
|
|
||||||
|
@ParametersAreNonnullByDefault
|
||||||
public MultiBlockMachine(Category category, SlimefunItemStack item, ItemStack[] recipe, ItemStack[] machineRecipes, BlockFace trigger) {
|
public MultiBlockMachine(Category category, SlimefunItemStack item, ItemStack[] recipe, ItemStack[] machineRecipes, BlockFace trigger) {
|
||||||
super(category, item, RecipeType.MULTIBLOCK, recipe);
|
super(category, item, RecipeType.MULTIBLOCK, recipe);
|
||||||
this.recipes = new ArrayList<>();
|
this.recipes = new ArrayList<>();
|
||||||
@ -61,6 +63,7 @@ public abstract class MultiBlockMachine extends SlimefunItem implements NotPlace
|
|||||||
registerDefaultRecipes(displayRecipes);
|
registerDefaultRecipes(displayRecipes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ParametersAreNonnullByDefault
|
||||||
public MultiBlockMachine(Category category, SlimefunItemStack item, ItemStack[] recipe, BlockFace trigger) {
|
public MultiBlockMachine(Category category, SlimefunItemStack item, ItemStack[] recipe, BlockFace trigger) {
|
||||||
this(category, item, recipe, new ItemStack[0], trigger);
|
this(category, item, recipe, new ItemStack[0], trigger);
|
||||||
}
|
}
|
||||||
@ -114,10 +117,11 @@ public abstract class MultiBlockMachine extends SlimefunItem implements NotPlace
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
protected MultiBlockInteractionHandler getInteractionHandler() {
|
protected MultiBlockInteractionHandler getInteractionHandler() {
|
||||||
return (p, mb, b) -> {
|
return (p, mb, b) -> {
|
||||||
if (mb.equals(getMultiBlock())) {
|
if (mb.equals(getMultiBlock())) {
|
||||||
if (!isDisabled() && SlimefunPlugin.getProtectionManager().hasPermission(p, b.getLocation(), ProtectableAction.INTERACT_BLOCK) && Slimefun.hasUnlocked(p, this, true)) {
|
if (canUse(p, true) && SlimefunPlugin.getProtectionManager().hasPermission(p, b.getLocation(), ProtectableAction.INTERACT_BLOCK)) {
|
||||||
onInteract(p, b);
|
onInteract(p, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,17 +146,25 @@ public abstract class MultiBlockMachine extends SlimefunItem implements NotPlace
|
|||||||
* The {@link Block} of our {@link Dispenser}
|
* The {@link Block} of our {@link Dispenser}
|
||||||
* @param dispInv
|
* @param dispInv
|
||||||
* The {@link Inventory} of our {@link Dispenser}
|
* The {@link Inventory} of our {@link Dispenser}
|
||||||
|
*
|
||||||
* @return The target {@link Inventory}
|
* @return The target {@link Inventory}
|
||||||
*/
|
*/
|
||||||
|
@Nullable
|
||||||
|
@ParametersAreNonnullByDefault
|
||||||
protected Inventory findOutputInventory(ItemStack adding, Block dispBlock, Inventory dispInv) {
|
protected Inventory findOutputInventory(ItemStack adding, Block dispBlock, Inventory dispInv) {
|
||||||
return findOutputInventory(adding, dispBlock, dispInv, dispInv);
|
return findOutputInventory(adding, dispBlock, dispInv, dispInv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@ParametersAreNonnullByDefault
|
||||||
protected Inventory findOutputInventory(ItemStack product, Block dispBlock, Inventory dispInv, Inventory placeCheckerInv) {
|
protected Inventory findOutputInventory(ItemStack product, Block dispBlock, Inventory dispInv, Inventory placeCheckerInv) {
|
||||||
Inventory outputInv = findOutputChest(dispBlock, product);
|
Inventory outputInv = findOutputChest(dispBlock, product);
|
||||||
|
|
||||||
// This if-clause will trigger if no suitable output chest was found. It's functionally the same as the old fit
|
/*
|
||||||
// check for the dispenser, only refactored.
|
* This if-clause will trigger if no suitable output chest was found.
|
||||||
|
* It's functionally the same as the old fit check for the dispenser,
|
||||||
|
* only refactored.
|
||||||
|
*/
|
||||||
if (outputInv == null && InvUtils.fits(placeCheckerInv, product)) {
|
if (outputInv == null && InvUtils.fits(placeCheckerInv, product)) {
|
||||||
return dispInv;
|
return dispInv;
|
||||||
} else {
|
} else {
|
||||||
@ -166,9 +178,9 @@ public abstract class MultiBlockMachine extends SlimefunItem implements NotPlace
|
|||||||
Block potentialOutput = b.getRelative(face);
|
Block potentialOutput = b.getRelative(face);
|
||||||
|
|
||||||
if (potentialOutput.getType() == Material.CHEST) {
|
if (potentialOutput.getType() == Material.CHEST) {
|
||||||
String id = BlockStorage.checkID(potentialOutput);
|
SlimefunItem slimefunItem = BlockStorage.check(potentialOutput);
|
||||||
|
|
||||||
if (id != null && id.equals("OUTPUT_CHEST")) {
|
if (slimefunItem instanceof OutputChest) {
|
||||||
// Found the output chest! Now, let's check if we can fit the product in it.
|
// Found the output chest! Now, let's check if we can fit the product in it.
|
||||||
BlockState state = PaperLib.getBlockState(potentialOutput, false).getState();
|
BlockState state = PaperLib.getBlockState(potentialOutput, false).getState();
|
||||||
|
|
||||||
@ -187,7 +199,7 @@ public abstract class MultiBlockMachine extends SlimefunItem implements NotPlace
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
private static Material[] convertItemStacksToMaterial(ItemStack[] items) {
|
private static Material[] convertItemStacksToMaterial(@Nonnull ItemStack[] items) {
|
||||||
List<Material> materials = new ArrayList<>();
|
List<Material> materials = new ArrayList<>();
|
||||||
|
|
||||||
for (ItemStack item : items) {
|
for (ItemStack item : items) {
|
||||||
|
@ -5,8 +5,10 @@ import java.util.HashMap;
|
|||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
import javax.annotation.ParametersAreNonnullByDefault;
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
|
|
||||||
@ -15,6 +17,7 @@ import org.bukkit.block.Block;
|
|||||||
import org.bukkit.inventory.Inventory;
|
import org.bukkit.inventory.Inventory;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
import io.github.thebusybiscuit.cscorelib2.blocks.BlockPosition;
|
||||||
import io.github.thebusybiscuit.slimefun4.core.networks.NetworkManager;
|
import io.github.thebusybiscuit.slimefun4.core.networks.NetworkManager;
|
||||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
|
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
|
||||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||||
@ -63,6 +66,7 @@ class CargoNetworkTask implements Runnable {
|
|||||||
public void run() {
|
public void run() {
|
||||||
long timestamp = System.nanoTime();
|
long timestamp = System.nanoTime();
|
||||||
|
|
||||||
|
try {
|
||||||
// Chest Terminal Code
|
// Chest Terminal Code
|
||||||
if (SlimefunPlugin.getIntegrations().isChestTerminalInstalled()) {
|
if (SlimefunPlugin.getIntegrations().isChestTerminalInstalled()) {
|
||||||
network.handleItemRequests(inventories, chestTerminalInputs, chestTerminalOutputs);
|
network.handleItemRequests(inventories, chestTerminalInputs, chestTerminalOutputs);
|
||||||
@ -89,6 +93,9 @@ class CargoNetworkTask implements Runnable {
|
|||||||
// This will deduct any CT timings and attribute them towards the actual terminal
|
// This will deduct any CT timings and attribute them towards the actual terminal
|
||||||
timestamp += network.updateTerminals(chestTerminalInputs);
|
timestamp += network.updateTerminals(chestTerminalInputs);
|
||||||
}
|
}
|
||||||
|
} catch (Exception | LinkageError x) {
|
||||||
|
SlimefunPlugin.logger().log(Level.SEVERE, x, () -> "An Exception was caught while ticking a Cargo network @ " + new BlockPosition(network.getRegulator()));
|
||||||
|
}
|
||||||
|
|
||||||
// Submit a timings report
|
// Submit a timings report
|
||||||
SlimefunPlugin.getProfiler().closeEntry(network.getRegulator(), SlimefunItems.CARGO_MANAGER.getItem(), timestamp);
|
SlimefunPlugin.getProfiler().closeEntry(network.getRegulator(), SlimefunItems.CARGO_MANAGER.getItem(), timestamp);
|
||||||
@ -150,7 +157,7 @@ class CargoNetworkTask implements Runnable {
|
|||||||
|
|
||||||
Deque<Location> destinations = new LinkedList<>(outputNodes);
|
Deque<Location> destinations = new LinkedList<>(outputNodes);
|
||||||
Config cfg = BlockStorage.getLocationInfo(inputNode);
|
Config cfg = BlockStorage.getLocationInfo(inputNode);
|
||||||
boolean roundrobin = "true".equals(cfg.getString("round-robin"));
|
boolean roundrobin = Objects.equals(cfg.getString("round-robin"), "true");
|
||||||
|
|
||||||
if (roundrobin) {
|
if (roundrobin) {
|
||||||
roundRobinSort(inputNode, destinations);
|
roundRobinSort(inputNode, destinations);
|
||||||
|
@ -240,11 +240,11 @@ final class CargoUtils {
|
|||||||
int maxSlot = range[1];
|
int maxSlot = range[1];
|
||||||
|
|
||||||
for (int slot = minSlot; slot < maxSlot; slot++) {
|
for (int slot = minSlot; slot < maxSlot; slot++) {
|
||||||
ItemStack is = contents[slot];
|
ItemStack item = contents[slot];
|
||||||
|
|
||||||
if (matchesFilter(network, node, is)) {
|
if (matchesFilter(network, node, item)) {
|
||||||
inv.setItem(slot, null);
|
inv.setItem(slot, null);
|
||||||
return new ItemStackAndInteger(is, slot);
|
return new ItemStackAndInteger(item, slot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@ import org.bukkit.Material;
|
|||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
import io.github.thebusybiscuit.slimefun4.implementation.items.cargo.CargoNode;
|
||||||
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
|
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
|
||||||
import io.github.thebusybiscuit.slimefun4.utils.itemstack.ItemStackWrapper;
|
import io.github.thebusybiscuit.slimefun4.utils.itemstack.ItemStackWrapper;
|
||||||
import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config;
|
import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config;
|
||||||
@ -81,18 +82,36 @@ class ItemFilter implements Predicate<ItemStack> {
|
|||||||
SlimefunItem item = SlimefunItem.getByID(id);
|
SlimefunItem item = SlimefunItem.getByID(id);
|
||||||
BlockMenu menu = BlockStorage.getInventory(b.getLocation());
|
BlockMenu menu = BlockStorage.getInventory(b.getLocation());
|
||||||
|
|
||||||
if (item == null || menu == null) {
|
if (!(item instanceof CargoNode) || menu == null) {
|
||||||
// Don't filter for a non-existing item (safety check)
|
// Don't filter for a non-existing item (safety check)
|
||||||
clear(false);
|
clear(false);
|
||||||
} else if (id.equals("CARGO_NODE_OUTPUT")) {
|
} else {
|
||||||
// Output Nodes have no filter, allow everything
|
try {
|
||||||
|
CargoNode node = (CargoNode) item;
|
||||||
|
|
||||||
|
if (!node.hasItemFilter()) {
|
||||||
|
// Node does not have a filter, allow everything
|
||||||
clear(true);
|
clear(true);
|
||||||
} else {
|
} else {
|
||||||
|
int[] slots = CargoUtils.getFilteringSlots();
|
||||||
|
int inventorySize = menu.toInventory().getSize();
|
||||||
|
|
||||||
|
if (inventorySize < slots[slots.length - 1]) {
|
||||||
|
/*
|
||||||
|
* Related to #2876
|
||||||
|
* The reason was a missing negation int he filtering statement above.
|
||||||
|
* However if that ever happens again, we will know the reason and be able
|
||||||
|
* to send a warning in response to it.
|
||||||
|
*/
|
||||||
|
item.warn("Cargo Node was marked as a 'filtering' node but has an insufficient inventory size (" + inventorySize + ")");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.items.clear();
|
this.items.clear();
|
||||||
this.checkLore = Objects.equals(blockData.getString("filter-lore"), "true");
|
this.checkLore = Objects.equals(blockData.getString("filter-lore"), "true");
|
||||||
this.rejectOnMatch = !Objects.equals(blockData.getString("filter-type"), "whitelist");
|
this.rejectOnMatch = !Objects.equals(blockData.getString("filter-type"), "whitelist");
|
||||||
|
|
||||||
for (int slot : CargoUtils.getFilteringSlots()) {
|
for (int slot : slots) {
|
||||||
ItemStack stack = menu.getItemInSlot(slot);
|
ItemStack stack = menu.getItemInSlot(slot);
|
||||||
|
|
||||||
if (stack != null && stack.getType() != Material.AIR) {
|
if (stack != null && stack.getType() != Material.AIR) {
|
||||||
@ -100,6 +119,10 @@ class ItemFilter implements Predicate<ItemStack> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} catch (Exception | LinkageError x) {
|
||||||
|
item.error("Something went wrong while updating the ItemFilter for this cargo node.", x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.dirty = false;
|
this.dirty = false;
|
||||||
}
|
}
|
||||||
|
@ -29,13 +29,25 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
|||||||
*/
|
*/
|
||||||
public class BackupService implements Runnable {
|
public class BackupService implements Runnable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The maximum amount of backups to maintain
|
||||||
|
*/
|
||||||
private static final int MAX_BACKUPS = 20;
|
private static final int MAX_BACKUPS = 20;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Our {@link DateTimeFormatter} for formatting file names.
|
||||||
|
*/
|
||||||
private final DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy-MM-dd-HH-mm", Locale.ROOT);
|
private final DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy-MM-dd-HH-mm", Locale.ROOT);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The directory in which to create the backups
|
||||||
|
*/
|
||||||
private final File directory = new File("data-storage/Slimefun/block-backups");
|
private final File directory = new File("data-storage/Slimefun/block-backups");
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
// Make sure that the directory exists.
|
||||||
|
if (directory.exists()) {
|
||||||
List<File> backups = Arrays.asList(directory.listFiles());
|
List<File> backups = Arrays.asList(directory.listFiles());
|
||||||
|
|
||||||
if (backups.size() > MAX_BACKUPS) {
|
if (backups.size() > MAX_BACKUPS) {
|
||||||
@ -60,7 +72,8 @@ public class BackupService implements Runnable {
|
|||||||
SlimefunPlugin.logger().log(Level.WARNING, "Could not create backup-file: {0}", file.getName());
|
SlimefunPlugin.logger().log(Level.WARNING, "Could not create backup-file: {0}", file.getName());
|
||||||
}
|
}
|
||||||
} catch (IOException x) {
|
} catch (IOException x) {
|
||||||
SlimefunPlugin.logger().log(Level.SEVERE, x, () -> "An Error occurred while creating a backup for Slimefun " + SlimefunPlugin.getVersion());
|
SlimefunPlugin.logger().log(Level.SEVERE, x, () -> "An Exception occurred while creating a backup for Slimefun " + SlimefunPlugin.getVersion());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -106,15 +106,19 @@ public class MetricsService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Load the jar file into a child class loader using the SF PluginClassLoader
|
/*
|
||||||
// as a parent.
|
* Load the jar file into a child class loader using the Slimefun
|
||||||
|
* PluginClassLoader as a parent.
|
||||||
|
*/
|
||||||
moduleClassLoader = URLClassLoader.newInstance(new URL[] { metricsModuleFile.toURI().toURL() }, plugin.getClass().getClassLoader());
|
moduleClassLoader = URLClassLoader.newInstance(new URL[] { metricsModuleFile.toURI().toURL() }, plugin.getClass().getClassLoader());
|
||||||
Class<?> metricsClass = moduleClassLoader.loadClass("dev.walshy.sfmetrics.MetricsModule");
|
Class<?> metricsClass = moduleClassLoader.loadClass("dev.walshy.sfmetrics.MetricsModule");
|
||||||
|
|
||||||
metricVersion = metricsClass.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 it has not been newly downloaded, auto-updates are enabled
|
||||||
|
* AND there's a new version then cleanup, download and start
|
||||||
|
*/
|
||||||
if (!hasDownloadedUpdate && hasAutoUpdates() && checkForUpdate(metricVersion)) {
|
if (!hasDownloadedUpdate && hasAutoUpdates() && checkForUpdate(metricVersion)) {
|
||||||
plugin.getLogger().info("Cleaned up, now re-loading Metrics-Module!");
|
plugin.getLogger().info("Cleaned up, now re-loading Metrics-Module!");
|
||||||
start();
|
start();
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package io.github.thebusybiscuit.slimefun4.core.services;
|
package io.github.thebusybiscuit.slimefun4.core.services;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
@ -10,6 +11,9 @@ import javax.annotation.Nonnull;
|
|||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import org.apache.commons.lang.Validate;
|
import org.apache.commons.lang.Validate;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Keyed;
|
||||||
|
import org.bukkit.NamespacedKey;
|
||||||
import org.bukkit.Server;
|
import org.bukkit.Server;
|
||||||
import org.bukkit.inventory.FurnaceRecipe;
|
import org.bukkit.inventory.FurnaceRecipe;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
@ -34,9 +38,19 @@ import io.github.thebusybiscuit.slimefun4.implementation.guide.SurvivalSlimefunG
|
|||||||
*/
|
*/
|
||||||
public class MinecraftRecipeService {
|
public class MinecraftRecipeService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Our {@link Plugin} instance
|
||||||
|
*/
|
||||||
private final Plugin plugin;
|
private final Plugin plugin;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The subscriber list for the {@link RecipeSnapshot}.
|
||||||
|
*/
|
||||||
private final List<Consumer<RecipeSnapshot>> subscriptions = new LinkedList<>();
|
private final List<Consumer<RecipeSnapshot>> subscriptions = new LinkedList<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Our {@link RecipeSnapshot} - The centerpiece of this class.
|
||||||
|
*/
|
||||||
private RecipeSnapshot snapshot;
|
private RecipeSnapshot snapshot;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -115,6 +129,7 @@ public class MinecraftRecipeService {
|
|||||||
*
|
*
|
||||||
* @param recipe
|
* @param recipe
|
||||||
* The {@link Recipe} to get the shape from
|
* The {@link Recipe} to get the shape from
|
||||||
|
*
|
||||||
* @return An Array of {@link RecipeChoice} representing the shape of this {@link Recipe}
|
* @return An Array of {@link RecipeChoice} representing the shape of this {@link Recipe}
|
||||||
*/
|
*/
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@ -149,6 +164,7 @@ public class MinecraftRecipeService {
|
|||||||
*
|
*
|
||||||
* @param item
|
* @param item
|
||||||
* The {@link ItemStack} for which to get the recipes
|
* The {@link ItemStack} for which to get the recipes
|
||||||
|
*
|
||||||
* @return An array of {@link Recipe Recipes} to craft the given {@link ItemStack}
|
* @return An array of {@link Recipe Recipes} to craft the given {@link ItemStack}
|
||||||
*/
|
*/
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@ -160,4 +176,27 @@ public class MinecraftRecipeService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This returns the corresponding {@link Keyed} {@link Recipe} for the given {@link NamespacedKey}.
|
||||||
|
* If no {@link Recipe} was found, null will be returned.
|
||||||
|
* This is a significantly faster method over {@link Bukkit#getRecipe(NamespacedKey)} since we
|
||||||
|
* operate on a cached {@link HashMap}
|
||||||
|
*
|
||||||
|
* @param key
|
||||||
|
* The {@link NamespacedKey}
|
||||||
|
*
|
||||||
|
* @return The corresponding {@link Recipe} or null
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public Recipe getRecipe(@Nonnull NamespacedKey key) {
|
||||||
|
Validate.notNull(key, "The NamespacedKey should not be null");
|
||||||
|
|
||||||
|
if (snapshot != null) {
|
||||||
|
// We operate on a cached HashMap which is much faster than Bukkit's method.
|
||||||
|
return snapshot.getRecipe(key);
|
||||||
|
} else {
|
||||||
|
return Bukkit.getRecipe(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package io.github.thebusybiscuit.slimefun4.core.services;
|
package io.github.thebusybiscuit.slimefun4.core.services;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -124,8 +123,7 @@ public class PermissionsService {
|
|||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public List<String> getLore(@Nonnull SlimefunItem item) {
|
public List<String> getLore(@Nonnull SlimefunItem item) {
|
||||||
List<String> lore = config.getStringList(item.getId() + ".lore");
|
return config.getStringList(item.getId() + ".lore");
|
||||||
return lore == null ? Arrays.asList("LORE NOT FOUND") : lore;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,9 @@ import io.github.thebusybiscuit.slimefun4.api.SlimefunBranch;
|
|||||||
import io.github.thebusybiscuit.slimefun4.core.services.LocalizationService;
|
import io.github.thebusybiscuit.slimefun4.core.services.LocalizationService;
|
||||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||||
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
|
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
|
||||||
|
import net.md_5.bungee.api.ChatMessageType;
|
||||||
|
import net.md_5.bungee.api.chat.BaseComponent;
|
||||||
|
import net.md_5.bungee.api.chat.TextComponent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is an abstract parent class of {@link LocalizationService}.
|
* This is an abstract parent class of {@link LocalizationService}.
|
||||||
@ -215,76 +218,84 @@ public abstract class SlimefunLocalization extends Localization implements Keyed
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendMessage(CommandSender sender, String key, boolean addPrefix) {
|
public void sendMessage(CommandSender recipient, String key, boolean addPrefix) {
|
||||||
String prefix = addPrefix ? getPrefix() : "";
|
String prefix = addPrefix ? getPrefix() : "";
|
||||||
|
|
||||||
if (sender instanceof Player) {
|
if (recipient instanceof Player) {
|
||||||
sender.sendMessage(ChatColors.color(prefix + getMessage((Player) sender, key)));
|
recipient.sendMessage(ChatColors.color(prefix + getMessage((Player) recipient, key)));
|
||||||
} else {
|
} else {
|
||||||
sender.sendMessage(ChatColor.stripColor(ChatColors.color(prefix + getMessage(key))));
|
recipient.sendMessage(ChatColor.stripColor(ChatColors.color(prefix + getMessage(key))));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void sendActionbarMessage(@Nonnull Player player, @Nonnull String key, boolean addPrefix) {
|
||||||
|
String prefix = addPrefix ? getPrefix() : "";
|
||||||
|
String message = ChatColors.color(prefix + getMessage(player, key));
|
||||||
|
|
||||||
|
BaseComponent[] components = TextComponent.fromLegacyText(message);
|
||||||
|
player.spigot().sendMessage(ChatMessageType.ACTION_BAR, components);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendMessage(CommandSender sender, String key) {
|
public void sendMessage(CommandSender recipient, String key) {
|
||||||
sendMessage(sender, key, true);
|
sendMessage(recipient, key, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendMessage(CommandSender sender, String key, UnaryOperator<String> function) {
|
public void sendMessage(CommandSender recipient, String key, UnaryOperator<String> function) {
|
||||||
sendMessage(sender, key, true, function);
|
sendMessage(recipient, key, true, function);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendMessage(CommandSender sender, String key, boolean addPrefix, UnaryOperator<String> function) {
|
public void sendMessage(CommandSender recipient, String key, boolean addPrefix, UnaryOperator<String> function) {
|
||||||
if (SlimefunPlugin.getMinecraftVersion() == MinecraftVersion.UNIT_TEST) {
|
if (SlimefunPlugin.getMinecraftVersion() == MinecraftVersion.UNIT_TEST) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
String prefix = addPrefix ? getPrefix() : "";
|
String prefix = addPrefix ? getPrefix() : "";
|
||||||
|
|
||||||
if (sender instanceof Player) {
|
if (recipient instanceof Player) {
|
||||||
sender.sendMessage(ChatColors.color(prefix + function.apply(getMessage((Player) sender, key))));
|
recipient.sendMessage(ChatColors.color(prefix + function.apply(getMessage((Player) recipient, key))));
|
||||||
} else {
|
} else {
|
||||||
sender.sendMessage(ChatColor.stripColor(ChatColors.color(prefix + function.apply(getMessage(key)))));
|
recipient.sendMessage(ChatColor.stripColor(ChatColors.color(prefix + function.apply(getMessage(key)))));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendMessages(CommandSender sender, String key) {
|
public void sendMessages(CommandSender recipient, String key) {
|
||||||
String prefix = getPrefix();
|
String prefix = getPrefix();
|
||||||
|
|
||||||
if (sender instanceof Player) {
|
if (recipient instanceof Player) {
|
||||||
for (String translation : getMessages((Player) sender, key)) {
|
for (String translation : getMessages((Player) recipient, key)) {
|
||||||
String message = ChatColors.color(prefix + translation);
|
String message = ChatColors.color(prefix + translation);
|
||||||
sender.sendMessage(message);
|
recipient.sendMessage(message);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (String translation : getMessages(key)) {
|
for (String translation : getMessages(key)) {
|
||||||
String message = ChatColors.color(prefix + translation);
|
String message = ChatColors.color(prefix + translation);
|
||||||
sender.sendMessage(ChatColor.stripColor(message));
|
recipient.sendMessage(ChatColor.stripColor(message));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendMessages(CommandSender sender, String key, boolean addPrefix, UnaryOperator<String> function) {
|
public void sendMessages(CommandSender recipient, String key, boolean addPrefix, UnaryOperator<String> function) {
|
||||||
String prefix = addPrefix ? getPrefix() : "";
|
String prefix = addPrefix ? getPrefix() : "";
|
||||||
|
|
||||||
if (sender instanceof Player) {
|
if (recipient instanceof Player) {
|
||||||
for (String translation : getMessages((Player) sender, key)) {
|
for (String translation : getMessages((Player) recipient, key)) {
|
||||||
String message = ChatColors.color(prefix + function.apply(translation));
|
String message = ChatColors.color(prefix + function.apply(translation));
|
||||||
sender.sendMessage(message);
|
recipient.sendMessage(message);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (String translation : getMessages(key)) {
|
for (String translation : getMessages(key)) {
|
||||||
String message = ChatColors.color(prefix + function.apply(translation));
|
String message = ChatColors.color(prefix + function.apply(translation));
|
||||||
sender.sendMessage(ChatColor.stripColor(message));
|
recipient.sendMessage(ChatColor.stripColor(message));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendMessages(CommandSender sender, String key, UnaryOperator<String> function) {
|
public void sendMessages(CommandSender recipient, String key, UnaryOperator<String> function) {
|
||||||
sendMessages(sender, key, true, function);
|
sendMessages(recipient, key, true, function);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -38,6 +38,7 @@ public class Translators {
|
|||||||
addTranslator("NinoFutur", SupportedLanguage.FRENCH, true);
|
addTranslator("NinoFutur", SupportedLanguage.FRENCH, true);
|
||||||
addTranslator("TheRetix", SupportedLanguage.FRENCH, true);
|
addTranslator("TheRetix", SupportedLanguage.FRENCH, true);
|
||||||
addTranslator("Aeris1One", SupportedLanguage.FRENCH, true);
|
addTranslator("Aeris1One", SupportedLanguage.FRENCH, true);
|
||||||
|
addTranslator("Aomitsu", SupportedLanguage.FRENCH, true);
|
||||||
|
|
||||||
// Translators - Italian
|
// Translators - Italian
|
||||||
addTranslator("xXDOTTORXx", SupportedLanguage.ITALIAN, true);
|
addTranslator("xXDOTTORXx", SupportedLanguage.ITALIAN, true);
|
||||||
@ -89,6 +90,9 @@ public class Translators {
|
|||||||
addTranslator("MrFriggo", SupportedLanguage.CZECH, true);
|
addTranslator("MrFriggo", SupportedLanguage.CZECH, true);
|
||||||
addTranslator("100petr", SupportedLanguage.CZECH, true);
|
addTranslator("100petr", SupportedLanguage.CZECH, true);
|
||||||
addTranslator("frfole", SupportedLanguage.CZECH, true);
|
addTranslator("frfole", SupportedLanguage.CZECH, true);
|
||||||
|
addTranslator("bobhenl", SupportedLanguage.CZECH, true);
|
||||||
|
addTranslator("janvrska", SupportedLanguage.CZECH, true);
|
||||||
|
addTranslator("LirCZE", SupportedLanguage.CZECH, true);
|
||||||
|
|
||||||
// Translators - Russian
|
// Translators - Russian
|
||||||
addTranslator("SoSeDiK", SupportedLanguage.RUSSIAN, false);
|
addTranslator("SoSeDiK", SupportedLanguage.RUSSIAN, false);
|
||||||
@ -103,6 +107,9 @@ public class Translators {
|
|||||||
addTranslator("NihilistBrew", "ma1yang2", SupportedLanguage.SWEDISH, false);
|
addTranslator("NihilistBrew", "ma1yang2", SupportedLanguage.SWEDISH, false);
|
||||||
addTranslator("Tra-sh", "TurretTrash", SupportedLanguage.SWEDISH, true);
|
addTranslator("Tra-sh", "TurretTrash", SupportedLanguage.SWEDISH, true);
|
||||||
|
|
||||||
|
// Translators - Finnish
|
||||||
|
addTranslator("developer-pseudo", SupportedLanguage.FINNISH, true);
|
||||||
|
|
||||||
// Translators - Dutch
|
// Translators - Dutch
|
||||||
addTranslator("Dr4gonD", "DragonD", SupportedLanguage.DUTCH, true);
|
addTranslator("Dr4gonD", "DragonD", SupportedLanguage.DUTCH, true);
|
||||||
addTranslator("svr333", SupportedLanguage.DUTCH, false);
|
addTranslator("svr333", SupportedLanguage.DUTCH, false);
|
||||||
@ -110,6 +117,7 @@ public class Translators {
|
|||||||
addTranslator("milvantiou", SupportedLanguage.DUTCH, true);
|
addTranslator("milvantiou", SupportedLanguage.DUTCH, true);
|
||||||
addTranslator("Sven313D", SupportedLanguage.DUTCH, true);
|
addTranslator("Sven313D", SupportedLanguage.DUTCH, true);
|
||||||
addTranslator("TypischTeun", SupportedLanguage.DUTCH, true);
|
addTranslator("TypischTeun", SupportedLanguage.DUTCH, true);
|
||||||
|
addTranslator("peppower", SupportedLanguage.DUTCH, true);
|
||||||
|
|
||||||
// Translators - Danish
|
// Translators - Danish
|
||||||
addTranslator("Mini-kun", SupportedLanguage.DANISH, true);
|
addTranslator("Mini-kun", SupportedLanguage.DANISH, true);
|
||||||
@ -124,6 +132,7 @@ public class Translators {
|
|||||||
addTranslator("StarWishsama", "StarWish_Sama", SupportedLanguage.CHINESE_CHINA, false);
|
addTranslator("StarWishsama", "StarWish_Sama", SupportedLanguage.CHINESE_CHINA, false);
|
||||||
addTranslator("Rothes", SupportedLanguage.CHINESE_CHINA, true);
|
addTranslator("Rothes", SupportedLanguage.CHINESE_CHINA, true);
|
||||||
addTranslator("Chihsiao", SupportedLanguage.CHINESE_CHINA, true);
|
addTranslator("Chihsiao", SupportedLanguage.CHINESE_CHINA, true);
|
||||||
|
addTranslator("Jiejue233", SupportedLanguage.CHINESE_CHINA, true);
|
||||||
|
|
||||||
// Translators - Chinese (Taiwan)
|
// Translators - Chinese (Taiwan)
|
||||||
addTranslator("BrineYT", "HeroBrineKing", SupportedLanguage.CHINESE_TAIWAN, true);
|
addTranslator("BrineYT", "HeroBrineKing", SupportedLanguage.CHINESE_TAIWAN, true);
|
||||||
|
@ -841,7 +841,9 @@ public final class SlimefunItems {
|
|||||||
public static final SlimefunItemStack ELECTRIC_INGOT_FACTORY_2 = new SlimefunItemStack("ELECTRIC_INGOT_FACTORY_2", Material.RED_TERRACOTTA, "&cElectric Ingot Factory &7(&eII&7)", "", LoreBuilder.machine(MachineTier.BASIC, MachineType.MACHINE), LoreBuilder.speed(2), LoreBuilder.powerPerSecond(14));
|
public static final SlimefunItemStack ELECTRIC_INGOT_FACTORY_2 = new SlimefunItemStack("ELECTRIC_INGOT_FACTORY_2", Material.RED_TERRACOTTA, "&cElectric Ingot Factory &7(&eII&7)", "", LoreBuilder.machine(MachineTier.BASIC, MachineType.MACHINE), LoreBuilder.speed(2), LoreBuilder.powerPerSecond(14));
|
||||||
public static final SlimefunItemStack ELECTRIC_INGOT_FACTORY_3 = new SlimefunItemStack("ELECTRIC_INGOT_FACTORY_3", Material.RED_TERRACOTTA, "&cElectric Ingot Factory &7(&eIII&7)", "", LoreBuilder.machine(MachineTier.END_GAME, MachineType.MACHINE), LoreBuilder.speed(8), LoreBuilder.powerPerSecond(40));
|
public static final SlimefunItemStack ELECTRIC_INGOT_FACTORY_3 = new SlimefunItemStack("ELECTRIC_INGOT_FACTORY_3", Material.RED_TERRACOTTA, "&cElectric Ingot Factory &7(&eIII&7)", "", LoreBuilder.machine(MachineTier.END_GAME, MachineType.MACHINE), LoreBuilder.speed(8), LoreBuilder.powerPerSecond(40));
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public static final SlimefunItemStack AUTOMATED_CRAFTING_CHAMBER = new SlimefunItemStack("AUTOMATED_CRAFTING_CHAMBER", Material.CRAFTING_TABLE, "&6Automated Crafting Chamber", "", LoreBuilder.machine(MachineTier.ADVANCED, MachineType.MACHINE), "&8\u21E8 &e\u26A1 &710 J/Item");
|
public static final SlimefunItemStack AUTOMATED_CRAFTING_CHAMBER = new SlimefunItemStack("AUTOMATED_CRAFTING_CHAMBER", Material.CRAFTING_TABLE, "&6Automated Crafting Chamber", "", LoreBuilder.machine(MachineTier.ADVANCED, MachineType.MACHINE), "&8\u21E8 &e\u26A1 &710 J/Item");
|
||||||
|
|
||||||
public static final SlimefunItemStack FLUID_PUMP = new SlimefunItemStack("FLUID_PUMP", Material.BLUE_TERRACOTTA, "&9Fluid Pump", "", LoreBuilder.machine(MachineTier.ADVANCED, MachineType.MACHINE), "&8\u21E8 &e\u26A1 &732 J/Block");
|
public static final SlimefunItemStack FLUID_PUMP = new SlimefunItemStack("FLUID_PUMP", Material.BLUE_TERRACOTTA, "&9Fluid Pump", "", LoreBuilder.machine(MachineTier.ADVANCED, MachineType.MACHINE), "&8\u21E8 &e\u26A1 &732 J/Block");
|
||||||
public static final SlimefunItemStack CHARGING_BENCH = new SlimefunItemStack("CHARGING_BENCH", Material.CRAFTING_TABLE, "&6Charging Bench", "", "&fCharges Items such as Jetpacks", "", LoreBuilder.machine(MachineTier.BASIC, MachineType.MACHINE), LoreBuilder.powerBuffer(128), "&8\u21E8 &e\u26A1 &7Energy Loss: &c50%");
|
public static final SlimefunItemStack CHARGING_BENCH = new SlimefunItemStack("CHARGING_BENCH", Material.CRAFTING_TABLE, "&6Charging Bench", "", "&fCharges Items such as Jetpacks", "", LoreBuilder.machine(MachineTier.BASIC, MachineType.MACHINE), LoreBuilder.powerBuffer(128), "&8\u21E8 &e\u26A1 &7Energy Loss: &c50%");
|
||||||
|
|
||||||
|
@ -78,6 +78,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.listeners.GrapplingHook
|
|||||||
import io.github.thebusybiscuit.slimefun4.implementation.listeners.HopperListener;
|
import io.github.thebusybiscuit.slimefun4.implementation.listeners.HopperListener;
|
||||||
import io.github.thebusybiscuit.slimefun4.implementation.listeners.ItemDropListener;
|
import io.github.thebusybiscuit.slimefun4.implementation.listeners.ItemDropListener;
|
||||||
import io.github.thebusybiscuit.slimefun4.implementation.listeners.ItemPickupListener;
|
import io.github.thebusybiscuit.slimefun4.implementation.listeners.ItemPickupListener;
|
||||||
|
import io.github.thebusybiscuit.slimefun4.implementation.listeners.MiningAndroidListener;
|
||||||
import io.github.thebusybiscuit.slimefun4.implementation.listeners.MultiBlockListener;
|
import io.github.thebusybiscuit.slimefun4.implementation.listeners.MultiBlockListener;
|
||||||
import io.github.thebusybiscuit.slimefun4.implementation.listeners.NetworkListener;
|
import io.github.thebusybiscuit.slimefun4.implementation.listeners.NetworkListener;
|
||||||
import io.github.thebusybiscuit.slimefun4.implementation.listeners.PlayerProfileListener;
|
import io.github.thebusybiscuit.slimefun4.implementation.listeners.PlayerProfileListener;
|
||||||
@ -128,14 +129,26 @@ import me.mrCookieSlime.Slimefun.api.inventory.UniversalBlockMenu;
|
|||||||
*/
|
*/
|
||||||
public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon {
|
public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Our static instance of {@link SlimefunPlugin}.
|
||||||
|
* Make sure to clean this up in {@link #onDisable()} !
|
||||||
|
*/
|
||||||
private static SlimefunPlugin instance;
|
private static SlimefunPlugin instance;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Keep track of which {@link MinecraftVersion} we are on.
|
||||||
|
*/
|
||||||
private MinecraftVersion minecraftVersion = MinecraftVersion.UNKNOWN;
|
private MinecraftVersion minecraftVersion = MinecraftVersion.UNKNOWN;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Keep track of whether this is a fresh install or a regular boot up.
|
||||||
|
*/
|
||||||
private boolean isNewlyInstalled = false;
|
private boolean isNewlyInstalled = false;
|
||||||
|
|
||||||
|
// Various things we need
|
||||||
private final SlimefunRegistry registry = new SlimefunRegistry();
|
private final SlimefunRegistry registry = new SlimefunRegistry();
|
||||||
private final TickerTask ticker = new TickerTask();
|
|
||||||
private final SlimefunCommand command = new SlimefunCommand(this);
|
private final SlimefunCommand command = new SlimefunCommand(this);
|
||||||
|
private final TickerTask ticker = new TickerTask();
|
||||||
|
|
||||||
// Services - Systems that fulfill certain tasks, treat them as a black box
|
// Services - Systems that fulfill certain tasks, treat them as a black box
|
||||||
private final CustomItemDataService itemDataService = new CustomItemDataService(this, "slimefun_item");
|
private final CustomItemDataService itemDataService = new CustomItemDataService(this, "slimefun_item");
|
||||||
@ -151,10 +164,12 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon {
|
|||||||
private final MinecraftRecipeService recipeService = new MinecraftRecipeService(this);
|
private final MinecraftRecipeService recipeService = new MinecraftRecipeService(this);
|
||||||
private final HologramsService hologramsService = new HologramsService(this);
|
private final HologramsService hologramsService = new HologramsService(this);
|
||||||
|
|
||||||
|
// Some other things we need
|
||||||
private final IntegrationsManager integrations = new IntegrationsManager(this);
|
private final IntegrationsManager integrations = new IntegrationsManager(this);
|
||||||
private final SlimefunProfiler profiler = new SlimefunProfiler();
|
private final SlimefunProfiler profiler = new SlimefunProfiler();
|
||||||
private final GPSNetwork gpsNetwork = new GPSNetwork(this);
|
private final GPSNetwork gpsNetwork = new GPSNetwork(this);
|
||||||
|
|
||||||
|
// Even more things we need
|
||||||
private NetworkManager networkManager;
|
private NetworkManager networkManager;
|
||||||
private LocalizationService local;
|
private LocalizationService local;
|
||||||
|
|
||||||
@ -231,6 +246,7 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon {
|
|||||||
private void onPluginStart() {
|
private void onPluginStart() {
|
||||||
long timestamp = System.nanoTime();
|
long timestamp = System.nanoTime();
|
||||||
|
|
||||||
|
// Check if Paper (<3) is installed
|
||||||
if (PaperLib.isPaper()) {
|
if (PaperLib.isPaper()) {
|
||||||
getLogger().log(Level.INFO, "Paper was detected! Performance optimizations have been applied.");
|
getLogger().log(Level.INFO, "Paper was detected! Performance optimizations have been applied.");
|
||||||
} else {
|
} else {
|
||||||
@ -256,6 +272,7 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon {
|
|||||||
|
|
||||||
int networkSize = config.getInt("networks.max-size");
|
int networkSize = config.getInt("networks.max-size");
|
||||||
|
|
||||||
|
// Make sure that the network size is a valid input
|
||||||
if (networkSize < 1) {
|
if (networkSize < 1) {
|
||||||
getLogger().log(Level.WARNING, "Your 'networks.max-size' setting is misconfigured! It must be at least 1, it was set to: {0}", networkSize);
|
getLogger().log(Level.WARNING, "Your 'networks.max-size' setting is misconfigured! It must be at least 1, it was set to: {0}", networkSize);
|
||||||
networkSize = 1;
|
networkSize = 1;
|
||||||
@ -359,8 +376,12 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon {
|
|||||||
Bukkit.getScheduler().cancelTasks(this);
|
Bukkit.getScheduler().cancelTasks(this);
|
||||||
|
|
||||||
// Finishes all started movements/removals of block data
|
// Finishes all started movements/removals of block data
|
||||||
|
try {
|
||||||
ticker.halt();
|
ticker.halt();
|
||||||
ticker.run();
|
ticker.run();
|
||||||
|
} catch (Exception x) {
|
||||||
|
getLogger().log(Level.SEVERE, x, () -> "Something went wrong while disabling the ticker task for Slimefun v" + getDescription().getVersion());
|
||||||
|
}
|
||||||
|
|
||||||
// Kill our Profiler Threads
|
// Kill our Profiler Threads
|
||||||
profiler.kill();
|
profiler.kill();
|
||||||
@ -594,8 +615,11 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon {
|
|||||||
new GrindstoneListener(this);
|
new GrindstoneListener(this);
|
||||||
new CartographyTableListener(this);
|
new CartographyTableListener(this);
|
||||||
new ButcherAndroidListener(this);
|
new ButcherAndroidListener(this);
|
||||||
|
new MiningAndroidListener(this);
|
||||||
new NetworkListener(this, networkManager);
|
new NetworkListener(this, networkManager);
|
||||||
new HopperListener(this);
|
new HopperListener(this);
|
||||||
|
new TalismanListener(this);
|
||||||
|
new SoulboundListener(this);
|
||||||
|
|
||||||
// Bees were added in 1.15
|
// Bees were added in 1.15
|
||||||
if (minecraftVersion.isAtLeast(MinecraftVersion.MINECRAFT_1_15)) {
|
if (minecraftVersion.isAtLeast(MinecraftVersion.MINECRAFT_1_15)) {
|
||||||
@ -617,15 +641,6 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon {
|
|||||||
bowListener.register(this);
|
bowListener.register(this);
|
||||||
backpackListener.register(this);
|
backpackListener.register(this);
|
||||||
|
|
||||||
// Toggleable Listeners for performance reasons
|
|
||||||
if (config.getBoolean("items.talismans")) {
|
|
||||||
new TalismanListener(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (config.getBoolean("items.soulbound")) {
|
|
||||||
new SoulboundListener(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle Slimefun Guide being given on Join
|
// Handle Slimefun Guide being given on Join
|
||||||
new SlimefunGuideListener(this, config.getBoolean("guide.receive-on-first-join"));
|
new SlimefunGuideListener(this, config.getBoolean("guide.receive-on-first-join"));
|
||||||
|
|
||||||
@ -640,7 +655,7 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon {
|
|||||||
* This (re)loads every {@link SlimefunTag}.
|
* This (re)loads every {@link SlimefunTag}.
|
||||||
*/
|
*/
|
||||||
private void loadTags() {
|
private void loadTags() {
|
||||||
for (SlimefunTag tag : SlimefunTag.valuesCache) {
|
for (SlimefunTag tag : SlimefunTag.values()) {
|
||||||
try {
|
try {
|
||||||
// Only reload "empty" (or unloaded) Tags
|
// Only reload "empty" (or unloaded) Tags
|
||||||
if (tag.isEmpty()) {
|
if (tag.isEmpty()) {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package io.github.thebusybiscuit.slimefun4.implementation.guide;
|
package io.github.thebusybiscuit.slimefun4.implementation.guide;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
|
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -73,7 +74,8 @@ public class CheatSheetSlimefunGuide extends SurvivalSlimefunGuide {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void createHeader(Player p, PlayerProfile profile, ChestMenu menu) {
|
@ParametersAreNonnullByDefault
|
||||||
|
public void createHeader(Player p, PlayerProfile profile, ChestMenu menu) {
|
||||||
super.createHeader(p, profile, menu);
|
super.createHeader(p, profile, menu);
|
||||||
|
|
||||||
// Remove Settings Panel
|
// Remove Settings Panel
|
||||||
|
@ -11,6 +11,7 @@ import java.util.logging.Level;
|
|||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.ParametersAreNonnullByDefault;
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
|
|
||||||
|
import org.apache.commons.lang.Validate;
|
||||||
import org.bukkit.ChatColor;
|
import org.bukkit.ChatColor;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.Sound;
|
import org.bukkit.Sound;
|
||||||
@ -76,6 +77,17 @@ public class SurvivalSlimefunGuide implements SlimefunGuideImplementation {
|
|||||||
item = new SlimefunGuideItem(this, "&aSlimefun Guide &7(Chest GUI)");
|
item = new SlimefunGuideItem(this, "&aSlimefun Guide &7(Chest GUI)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This returns the {@link Sound} which is played when someone navigates through
|
||||||
|
* the {@link SlimefunGuide}
|
||||||
|
*
|
||||||
|
* @return The {@link Sound}
|
||||||
|
*/
|
||||||
|
@Nonnull
|
||||||
|
public Sound getSound() {
|
||||||
|
return sound;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SlimefunGuideMode getMode() {
|
public SlimefunGuideMode getMode() {
|
||||||
return SlimefunGuideMode.SURVIVAL_MODE;
|
return SlimefunGuideMode.SURVIVAL_MODE;
|
||||||
@ -224,11 +236,7 @@ public class SurvivalSlimefunGuide implements SlimefunGuideImplementation {
|
|||||||
ChestMenu menu = create(p);
|
ChestMenu menu = create(p);
|
||||||
createHeader(p, profile, menu);
|
createHeader(p, profile, menu);
|
||||||
|
|
||||||
menu.addItem(1, new CustomItem(ChestMenuUtils.getBackButton(p, "", ChatColor.GRAY + SlimefunPlugin.getLocalization().getMessage(p, "guide.back.guide"))));
|
addBackButton(menu, 1, p, profile);
|
||||||
menu.addMenuClickHandler(1, (pl, s, is, action) -> {
|
|
||||||
openMainMenu(profile, 1);
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
int pages = (category.getItems().size() - 1) / CATEGORY_SIZE + 1;
|
int pages = (category.getItems().size() - 1) / CATEGORY_SIZE + 1;
|
||||||
|
|
||||||
@ -266,7 +274,7 @@ public class SurvivalSlimefunGuide implements SlimefunGuideImplementation {
|
|||||||
|
|
||||||
SlimefunItem sfitem = category.getItems().get(target);
|
SlimefunItem sfitem = category.getItems().get(target);
|
||||||
|
|
||||||
if (Slimefun.isEnabled(p, sfitem, false)) {
|
if (!sfitem.isDisabledIn(p.getWorld())) {
|
||||||
displaySlimefunItem(menu, category, p, profile, sfitem, page, index);
|
displaySlimefunItem(menu, category, p, profile, sfitem, page, index);
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
@ -552,7 +560,12 @@ public class SurvivalSlimefunGuide implements SlimefunGuideImplementation {
|
|||||||
menu.addItem(16, output, ChestMenuUtils.getEmptyClickHandler());
|
menu.addItem(16, output, ChestMenuUtils.getEmptyClickHandler());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void createHeader(Player p, PlayerProfile profile, ChestMenu menu) {
|
@ParametersAreNonnullByDefault
|
||||||
|
public void createHeader(Player p, PlayerProfile profile, ChestMenu menu) {
|
||||||
|
Validate.notNull(p, "The Player cannot be null!");
|
||||||
|
Validate.notNull(profile, "The Profile cannot be null!");
|
||||||
|
Validate.notNull(menu, "The Inventory cannot be null!");
|
||||||
|
|
||||||
for (int i = 0; i < 9; i++) {
|
for (int i = 0; i < 9; i++) {
|
||||||
menu.addItem(i, ChestMenuUtils.getBackground(), ChestMenuUtils.getEmptyClickHandler());
|
menu.addItem(i, ChestMenuUtils.getBackground(), ChestMenuUtils.getEmptyClickHandler());
|
||||||
}
|
}
|
||||||
@ -613,7 +626,7 @@ public class SurvivalSlimefunGuide implements SlimefunGuideImplementation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String lore = Slimefun.hasPermission(p, slimefunItem, false) ? "&fNeeds to be unlocked elsewhere" : "&fNo Permission";
|
String lore = Slimefun.hasPermission(p, slimefunItem, false) ? "&fNeeds to be unlocked elsewhere" : "&fNo Permission";
|
||||||
return Slimefun.hasUnlocked(p, slimefunItem, false) ? item : new CustomItem(Material.BARRIER, ItemUtils.getItemName(item), "&4&l" + SlimefunPlugin.getLocalization().getMessage(p, "guide.locked"), "", lore);
|
return slimefunItem.canUse(p, false) ? item : new CustomItem(Material.BARRIER, ItemUtils.getItemName(item), "&4&l" + SlimefunPlugin.getLocalization().getMessage(p, "guide.locked"), "", lore);
|
||||||
} else {
|
} else {
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,59 @@
|
|||||||
|
package io.github.thebusybiscuit.slimefun4.implementation.handlers;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
|
import org.bukkit.block.Block;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.block.BlockBreakEvent;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
import io.github.thebusybiscuit.slimefun4.api.events.AndroidMineEvent;
|
||||||
|
import io.github.thebusybiscuit.slimefun4.core.handlers.BlockBreakHandler;
|
||||||
|
import io.github.thebusybiscuit.slimefun4.implementation.items.androids.MinerAndroid;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This simple implementation of {@link BlockBreakHandler} will execute the same code
|
||||||
|
* for when the {@link Block} is broken by a {@link Player}, by a {@link MinerAndroid} or an explosion.
|
||||||
|
* By default, both androids and explosions are allowed.
|
||||||
|
*
|
||||||
|
* @author TheBusyBiscuit
|
||||||
|
*
|
||||||
|
* @see BlockBreakHandler
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public abstract class SimpleBlockBreakHandler extends BlockBreakHandler {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This constructs a new {@link SimpleBlockBreakHandler}.
|
||||||
|
*/
|
||||||
|
public SimpleBlockBreakHandler() {
|
||||||
|
super(true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is called when a {@link Block} of this type is broken by a {@link Player},
|
||||||
|
* by a {@link MinerAndroid} or through an explosion.
|
||||||
|
*
|
||||||
|
* @param b
|
||||||
|
* The broken {@link Block}
|
||||||
|
*/
|
||||||
|
public abstract void onBlockBreak(@Nonnull Block b);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPlayerBreak(BlockBreakEvent e, ItemStack item, List<ItemStack> drops) {
|
||||||
|
onBlockBreak(e.getBlock());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAndroidBreak(AndroidMineEvent e) {
|
||||||
|
onBlockBreak(e.getBlock());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onExplode(Block b, List<ItemStack> drops) {
|
||||||
|
onBlockBreak(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
/**
|
||||||
|
* This package holds simple implementations of {@link me.mrCookieSlime.Slimefun.Objects.handlers.ItemHandler}.
|
||||||
|
* These are just handlers that can be re-used frequently.
|
||||||
|
*/
|
||||||
|
package io.github.thebusybiscuit.slimefun4.implementation.handlers;
|
@ -21,15 +21,16 @@ import org.bukkit.util.Vector;
|
|||||||
import io.github.thebusybiscuit.cscorelib2.chat.ChatColors;
|
import io.github.thebusybiscuit.cscorelib2.chat.ChatColors;
|
||||||
import io.github.thebusybiscuit.cscorelib2.inventory.ItemUtils;
|
import io.github.thebusybiscuit.cscorelib2.inventory.ItemUtils;
|
||||||
import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
|
import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
|
||||||
|
import io.github.thebusybiscuit.slimefun4.core.handlers.BlockBreakHandler;
|
||||||
import io.github.thebusybiscuit.slimefun4.core.handlers.BlockDispenseHandler;
|
import io.github.thebusybiscuit.slimefun4.core.handlers.BlockDispenseHandler;
|
||||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||||
|
import io.github.thebusybiscuit.slimefun4.implementation.handlers.SimpleBlockBreakHandler;
|
||||||
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
|
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
|
||||||
import io.github.thebusybiscuit.slimefun4.implementation.listeners.AncientAltarListener;
|
import io.github.thebusybiscuit.slimefun4.implementation.listeners.AncientAltarListener;
|
||||||
import io.github.thebusybiscuit.slimefun4.implementation.tasks.AncientAltarTask;
|
import io.github.thebusybiscuit.slimefun4.implementation.tasks.AncientAltarTask;
|
||||||
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
|
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
|
||||||
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
|
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
|
||||||
import me.mrCookieSlime.Slimefun.Objects.Category;
|
import me.mrCookieSlime.Slimefun.Objects.Category;
|
||||||
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
|
|
||||||
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -53,7 +54,15 @@ public class AncientPedestal extends SimpleSlimefunItem<BlockDispenseHandler> {
|
|||||||
public AncientPedestal(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe, ItemStack recipeOutput) {
|
public AncientPedestal(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe, ItemStack recipeOutput) {
|
||||||
super(category, item, recipeType, recipe, recipeOutput);
|
super(category, item, recipeType, recipe, recipeOutput);
|
||||||
|
|
||||||
SlimefunItem.registerBlockHandler(getId(), (p, b, tool, reason) -> {
|
addItemHandler(onBreak());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
private BlockBreakHandler onBreak() {
|
||||||
|
return new SimpleBlockBreakHandler() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBlockBreak(@Nonnull Block b) {
|
||||||
Optional<Item> entity = getPlacedItem(b);
|
Optional<Item> entity = getPlacedItem(b);
|
||||||
|
|
||||||
if (entity.isPresent()) {
|
if (entity.isPresent()) {
|
||||||
@ -65,9 +74,8 @@ public class AncientPedestal extends SimpleSlimefunItem<BlockDispenseHandler> {
|
|||||||
stack.remove();
|
stack.remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return true;
|
};
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -3,40 +3,73 @@ package io.github.thebusybiscuit.slimefun4.implementation.items.androids;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Effect;
|
import org.bukkit.Effect;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.OfflinePlayer;
|
import org.bukkit.OfflinePlayer;
|
||||||
|
import org.bukkit.Particle;
|
||||||
|
import org.bukkit.Sound;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.block.BlockFace;
|
import org.bukkit.block.BlockFace;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction;
|
import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction;
|
||||||
import io.github.thebusybiscuit.slimefun4.api.events.AndroidMineEvent;
|
import io.github.thebusybiscuit.slimefun4.api.events.AndroidMineEvent;
|
||||||
|
import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting;
|
||||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||||
|
import io.github.thebusybiscuit.slimefun4.utils.InfiniteBlockGenerator;
|
||||||
import io.github.thebusybiscuit.slimefun4.utils.tags.SlimefunTag;
|
import io.github.thebusybiscuit.slimefun4.utils.tags.SlimefunTag;
|
||||||
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
|
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
|
||||||
import me.mrCookieSlime.Slimefun.Objects.Category;
|
import me.mrCookieSlime.Slimefun.Objects.Category;
|
||||||
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
|
|
||||||
import me.mrCookieSlime.Slimefun.api.BlockStorage;
|
import me.mrCookieSlime.Slimefun.api.BlockStorage;
|
||||||
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
||||||
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu;
|
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link MinerAndroid} is a variant of the {@link ProgrammableAndroid} which
|
||||||
|
* is able to break blocks.
|
||||||
|
* The core functionalities boil down to {@link #dig(Block, BlockMenu, Block)} and
|
||||||
|
* {@link #moveAndDig(Block, BlockMenu, BlockFace, Block)}.
|
||||||
|
* Otherwise the functionality is similar to a regular android.
|
||||||
|
* <p>
|
||||||
|
* The {@link MinerAndroid} will also fire an {@link AndroidMineEvent} when breaking a {@link Block}.
|
||||||
|
*
|
||||||
|
* @author TheBusyBiscuit
|
||||||
|
* @author creator3
|
||||||
|
* @author poma123
|
||||||
|
* @author Sfiguz7
|
||||||
|
* @author CyberPatriot
|
||||||
|
* @author Redemption198
|
||||||
|
* @author Poslovitch
|
||||||
|
*
|
||||||
|
* @see AndroidMineEvent
|
||||||
|
*
|
||||||
|
*/
|
||||||
public class MinerAndroid extends ProgrammableAndroid {
|
public class MinerAndroid extends ProgrammableAndroid {
|
||||||
|
|
||||||
// Determines the drops a miner android will get
|
// Determines the drops a miner android will get
|
||||||
private final ItemStack effectivePickaxe = new ItemStack(Material.DIAMOND_PICKAXE);
|
private final ItemStack effectivePickaxe = new ItemStack(Material.DIAMOND_PICKAXE);
|
||||||
|
|
||||||
|
private final ItemSetting<Boolean> firesEvent = new ItemSetting<>("trigger-event-for-generators", false);
|
||||||
|
private final ItemSetting<Boolean> applyOptimizations = new ItemSetting<>("reduced-block-updates", true);
|
||||||
|
|
||||||
|
@ParametersAreNonnullByDefault
|
||||||
public MinerAndroid(Category category, int tier, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
public MinerAndroid(Category category, int tier, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
||||||
super(category, tier, item, recipeType, recipe);
|
super(category, tier, item, recipeType, recipe);
|
||||||
|
addItemSetting(firesEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Nonnull
|
||||||
public AndroidType getAndroidType() {
|
public AndroidType getAndroidType() {
|
||||||
return AndroidType.MINER;
|
return AndroidType.MINER;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ParametersAreNonnullByDefault
|
||||||
protected void dig(Block b, BlockMenu menu, Block block) {
|
protected void dig(Block b, BlockMenu menu, Block block) {
|
||||||
Collection<ItemStack> drops = block.getDrops(effectivePickaxe);
|
Collection<ItemStack> drops = block.getDrops(effectivePickaxe);
|
||||||
|
|
||||||
@ -52,22 +85,16 @@ public class MinerAndroid extends ProgrammableAndroid {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// We only want to break non-Slimefun blocks
|
// We only want to break non-Slimefun blocks
|
||||||
String blockId = BlockStorage.checkID(block);
|
if (!BlockStorage.hasBlockInfo(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.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, block.getType());
|
||||||
block.setType(Material.AIR);
|
breakBlock(menu, drops, block);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ParametersAreNonnullByDefault
|
||||||
protected void moveAndDig(Block b, BlockMenu menu, BlockFace face, Block block) {
|
protected void moveAndDig(Block b, BlockMenu menu, BlockFace face, Block block) {
|
||||||
Collection<ItemStack> drops = block.getDrops(effectivePickaxe);
|
Collection<ItemStack> drops = block.getDrops(effectivePickaxe);
|
||||||
|
|
||||||
@ -83,24 +110,44 @@ public class MinerAndroid extends ProgrammableAndroid {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// We only want to break non-Slimefun blocks
|
// We only want to break non-Slimefun blocks
|
||||||
SlimefunItem blockId = BlockStorage.check(block);
|
if (!BlockStorage.hasBlockInfo(block)) {
|
||||||
if (blockId == null) {
|
block.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, block.getType());
|
||||||
|
breakBlock(menu, drops, block);
|
||||||
|
move(b, face, block);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
move(b, face, block);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
move(b, face, block);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParametersAreNonnullByDefault
|
||||||
|
private void breakBlock(BlockMenu menu, Collection<ItemStack> drops, Block block) {
|
||||||
|
// Push our drops to the inventory
|
||||||
for (ItemStack drop : drops) {
|
for (ItemStack drop : drops) {
|
||||||
if (menu.fits(drop, getOutputSlots())) {
|
|
||||||
menu.pushItem(drop, getOutputSlots());
|
menu.pushItem(drop, getOutputSlots());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if Block Generator optimizations should be applied.
|
||||||
|
if (applyOptimizations.getValue()) {
|
||||||
|
InfiniteBlockGenerator generator = InfiniteBlockGenerator.findAt(block);
|
||||||
|
|
||||||
|
// If we found a generator, continue.
|
||||||
|
if (generator != null) {
|
||||||
|
if (firesEvent.getValue()) {
|
||||||
|
generator.callEvent(block);
|
||||||
}
|
}
|
||||||
|
|
||||||
block.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, block.getType());
|
// "poof" a "new" block was generated
|
||||||
|
block.getWorld().playSound(block.getLocation(), Sound.BLOCK_FIRE_EXTINGUISH, 0.075F, 0.8F);
|
||||||
|
block.getWorld().spawnParticle(Particle.SMOKE_NORMAL, block.getX() + 0.5, block.getY() + 1.25, block.getZ() + 0.5, 8, 0.5, 0.5, 0.5, 0.015);
|
||||||
|
} else {
|
||||||
block.setType(Material.AIR);
|
block.setType(Material.AIR);
|
||||||
move(b, face, block);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
move(b, face, block);
|
block.setType(Material.AIR);
|
||||||
}
|
|
||||||
} else {
|
|
||||||
move(b, face, block);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,7 +56,6 @@ import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.UnregisterReason;
|
|||||||
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.MachineFuel;
|
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.MachineFuel;
|
||||||
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.interfaces.InventoryBlock;
|
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.interfaces.InventoryBlock;
|
||||||
import me.mrCookieSlime.Slimefun.Objects.handlers.BlockTicker;
|
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.BlockStorage;
|
||||||
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
||||||
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu;
|
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu;
|
||||||
@ -133,6 +132,7 @@ public class ProgrammableAndroid extends SlimefunItem implements InventoryBlock,
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// TODO: Move this into a BlockBreakHandler
|
||||||
registerBlockHandler(getId(), (p, b, stack, reason) -> {
|
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"));
|
boolean allow = reason == UnregisterReason.PLAYER_BREAK && (BlockStorage.getLocationInfo(b.getLocation(), "owner").equals(p.getUniqueId().toString()) || p.hasPermission("slimefun.android.bypass"));
|
||||||
|
|
||||||
@ -151,7 +151,8 @@ public class ProgrammableAndroid extends SlimefunItem implements InventoryBlock,
|
|||||||
addItemHandler(onPlace());
|
addItemHandler(onPlace());
|
||||||
}
|
}
|
||||||
|
|
||||||
private ItemHandler onPlace() {
|
@Nonnull
|
||||||
|
private BlockPlaceHandler onPlace() {
|
||||||
return new BlockPlaceHandler(false) {
|
return new BlockPlaceHandler(false) {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
package io.github.thebusybiscuit.slimefun4.implementation.items.androids;
|
package io.github.thebusybiscuit.slimefun4.implementation.items.androids;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Effect;
|
import org.bukkit.Effect;
|
||||||
@ -14,9 +17,10 @@ import org.bukkit.block.BlockFace;
|
|||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
import io.github.thebusybiscuit.cscorelib2.blocks.Vein;
|
import io.github.thebusybiscuit.cscorelib2.blocks.Vein;
|
||||||
import io.github.thebusybiscuit.cscorelib2.materials.MaterialConverter;
|
|
||||||
import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction;
|
import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction;
|
||||||
|
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
|
||||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||||
|
import io.github.thebusybiscuit.slimefun4.utils.tags.SlimefunTag;
|
||||||
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
|
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
|
||||||
import me.mrCookieSlime.Slimefun.Objects.Category;
|
import me.mrCookieSlime.Slimefun.Objects.Category;
|
||||||
import me.mrCookieSlime.Slimefun.api.BlockStorage;
|
import me.mrCookieSlime.Slimefun.api.BlockStorage;
|
||||||
@ -59,6 +63,7 @@ public class WoodcutterAndroid extends ProgrammableAndroid {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ParametersAreNonnullByDefault
|
||||||
private void breakLog(Block log, Block android, BlockMenu menu, BlockFace face) {
|
private void breakLog(Block log, Block android, BlockMenu menu, BlockFace face) {
|
||||||
ItemStack drop = new ItemStack(log.getType());
|
ItemStack drop = new ItemStack(log.getType());
|
||||||
|
|
||||||
@ -67,13 +72,96 @@ public class WoodcutterAndroid extends ProgrammableAndroid {
|
|||||||
log.getWorld().playEffect(log.getLocation(), Effect.STEP_SOUND, log.getType());
|
log.getWorld().playEffect(log.getLocation(), Effect.STEP_SOUND, log.getType());
|
||||||
|
|
||||||
if (log.getY() == android.getRelative(face).getY()) {
|
if (log.getY() == android.getRelative(face).getY()) {
|
||||||
Optional<Material> sapling = MaterialConverter.getSaplingFromLog(log.getType());
|
replant(log);
|
||||||
|
|
||||||
sapling.ifPresent(log::setType);
|
|
||||||
} else {
|
} else {
|
||||||
log.setType(Material.AIR);
|
log.setType(Material.AIR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void replant(@Nonnull Block block) {
|
||||||
|
Material logType = block.getType();
|
||||||
|
Material saplingType = null;
|
||||||
|
Predicate<Material> soilRequirement = null;
|
||||||
|
|
||||||
|
switch (logType) {
|
||||||
|
case OAK_LOG:
|
||||||
|
case OAK_WOOD:
|
||||||
|
case STRIPPED_OAK_LOG:
|
||||||
|
case STRIPPED_OAK_WOOD:
|
||||||
|
saplingType = Material.OAK_SAPLING;
|
||||||
|
soilRequirement = SlimefunTag.DIRT_VARIANTS::isTagged;
|
||||||
|
break;
|
||||||
|
case BIRCH_LOG:
|
||||||
|
case BIRCH_WOOD:
|
||||||
|
case STRIPPED_BIRCH_LOG:
|
||||||
|
case STRIPPED_BIRCH_WOOD:
|
||||||
|
saplingType = Material.BIRCH_SAPLING;
|
||||||
|
soilRequirement = SlimefunTag.DIRT_VARIANTS::isTagged;
|
||||||
|
break;
|
||||||
|
case JUNGLE_LOG:
|
||||||
|
case JUNGLE_WOOD:
|
||||||
|
case STRIPPED_JUNGLE_LOG:
|
||||||
|
case STRIPPED_JUNGLE_WOOD:
|
||||||
|
saplingType = Material.JUNGLE_SAPLING;
|
||||||
|
soilRequirement = SlimefunTag.DIRT_VARIANTS::isTagged;
|
||||||
|
break;
|
||||||
|
case SPRUCE_LOG:
|
||||||
|
case SPRUCE_WOOD:
|
||||||
|
case STRIPPED_SPRUCE_LOG:
|
||||||
|
case STRIPPED_SPRUCE_WOOD:
|
||||||
|
saplingType = Material.SPRUCE_SAPLING;
|
||||||
|
soilRequirement = SlimefunTag.DIRT_VARIANTS::isTagged;
|
||||||
|
break;
|
||||||
|
case ACACIA_LOG:
|
||||||
|
case ACACIA_WOOD:
|
||||||
|
case STRIPPED_ACACIA_LOG:
|
||||||
|
case STRIPPED_ACACIA_WOOD:
|
||||||
|
saplingType = Material.ACACIA_SAPLING;
|
||||||
|
soilRequirement = SlimefunTag.DIRT_VARIANTS::isTagged;
|
||||||
|
break;
|
||||||
|
case DARK_OAK_LOG:
|
||||||
|
case DARK_OAK_WOOD:
|
||||||
|
case STRIPPED_DARK_OAK_LOG:
|
||||||
|
case STRIPPED_DARK_OAK_WOOD:
|
||||||
|
saplingType = Material.DARK_OAK_SAPLING;
|
||||||
|
soilRequirement = SlimefunTag.DIRT_VARIANTS::isTagged;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SlimefunPlugin.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_16)) {
|
||||||
|
switch (logType) {
|
||||||
|
case CRIMSON_STEM:
|
||||||
|
case CRIMSON_HYPHAE:
|
||||||
|
case STRIPPED_CRIMSON_STEM:
|
||||||
|
case STRIPPED_CRIMSON_HYPHAE:
|
||||||
|
saplingType = Material.CRIMSON_FUNGUS;
|
||||||
|
soilRequirement = SlimefunTag.FUNGUS_SOIL::isTagged;
|
||||||
|
break;
|
||||||
|
case WARPED_STEM:
|
||||||
|
case WARPED_HYPHAE:
|
||||||
|
case STRIPPED_WARPED_STEM:
|
||||||
|
case STRIPPED_WARPED_HYPHAE:
|
||||||
|
saplingType = Material.WARPED_FUNGUS;
|
||||||
|
soilRequirement = SlimefunTag.FUNGUS_SOIL::isTagged;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (saplingType != null && soilRequirement != null) {
|
||||||
|
if (soilRequirement.test(block.getRelative(BlockFace.DOWN).getType())) {
|
||||||
|
// Replant the block
|
||||||
|
block.setType(saplingType);
|
||||||
|
} else {
|
||||||
|
// Simply drop the sapling if the soil does not fit
|
||||||
|
block.getWorld().dropItemNaturally(block.getLocation(), new ItemStack(saplingType));
|
||||||
|
block.setType(Material.AIR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,9 @@ package io.github.thebusybiscuit.slimefun4.implementation.items.blocks;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Effect;
|
import org.bukkit.Effect;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
@ -10,18 +13,21 @@ import org.bukkit.Material;
|
|||||||
import org.bukkit.Nameable;
|
import org.bukkit.Nameable;
|
||||||
import org.bukkit.OfflinePlayer;
|
import org.bukkit.OfflinePlayer;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
|
import org.bukkit.block.BlockState;
|
||||||
import org.bukkit.block.Dispenser;
|
import org.bukkit.block.Dispenser;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.block.BlockBreakEvent;
|
||||||
import org.bukkit.event.block.BlockPlaceEvent;
|
import org.bukkit.event.block.BlockPlaceEvent;
|
||||||
|
import org.bukkit.inventory.Inventory;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.inventory.meta.ItemMeta;
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
|
|
||||||
import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
|
|
||||||
import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction;
|
import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction;
|
||||||
import io.github.thebusybiscuit.slimefun4.api.events.BlockPlacerPlaceEvent;
|
import io.github.thebusybiscuit.slimefun4.api.events.BlockPlacerPlaceEvent;
|
||||||
import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting;
|
import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting;
|
||||||
import io.github.thebusybiscuit.slimefun4.api.items.settings.MaterialTagSetting;
|
import io.github.thebusybiscuit.slimefun4.api.items.settings.MaterialTagSetting;
|
||||||
import io.github.thebusybiscuit.slimefun4.core.attributes.NotPlaceable;
|
import io.github.thebusybiscuit.slimefun4.core.attributes.NotPlaceable;
|
||||||
|
import io.github.thebusybiscuit.slimefun4.core.handlers.BlockBreakHandler;
|
||||||
import io.github.thebusybiscuit.slimefun4.core.handlers.BlockDispenseHandler;
|
import io.github.thebusybiscuit.slimefun4.core.handlers.BlockDispenseHandler;
|
||||||
import io.github.thebusybiscuit.slimefun4.core.handlers.BlockPlaceHandler;
|
import io.github.thebusybiscuit.slimefun4.core.handlers.BlockPlaceHandler;
|
||||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||||
@ -47,15 +53,17 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
|||||||
*/
|
*/
|
||||||
public class BlockPlacer extends SlimefunItem {
|
public class BlockPlacer extends SlimefunItem {
|
||||||
|
|
||||||
private final ItemSetting<List<String>> blacklist = new MaterialTagSetting("unplaceable-blocks", SlimefunTag.UNBREAKABLE_MATERIALS);
|
private final ItemSetting<List<String>> unplaceableBlocks = new MaterialTagSetting("unplaceable-blocks", SlimefunTag.UNBREAKABLE_MATERIALS);
|
||||||
|
|
||||||
|
@ParametersAreNonnullByDefault
|
||||||
public BlockPlacer(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
public BlockPlacer(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
||||||
super(category, item, recipeType, recipe);
|
super(category, item, recipeType, recipe);
|
||||||
|
|
||||||
addItemSetting(blacklist);
|
addItemSetting(unplaceableBlocks);
|
||||||
addItemHandler(onPlace(), onBlockDispense());
|
addItemHandler(onPlace(), onBlockBreak(), onBlockDispense());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
private BlockPlaceHandler onPlace() {
|
private BlockPlaceHandler onPlace() {
|
||||||
return new BlockPlaceHandler(false) {
|
return new BlockPlaceHandler(false) {
|
||||||
|
|
||||||
@ -69,6 +77,33 @@ public class BlockPlacer extends SlimefunItem {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
private BlockBreakHandler onBlockBreak() {
|
||||||
|
/*
|
||||||
|
* Explosions don't need explicit handling here.
|
||||||
|
* The default of "destroy the dispenser and drop the contents" is
|
||||||
|
* fine for our purposes already.
|
||||||
|
*/
|
||||||
|
return new BlockBreakHandler(false, true) {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPlayerBreak(BlockBreakEvent e, ItemStack item, List<ItemStack> drops) {
|
||||||
|
// Fixes #2852 - Manually drop inventory contents
|
||||||
|
Block b = e.getBlock();
|
||||||
|
BlockState state = PaperLib.getBlockState(b, false).getState();
|
||||||
|
|
||||||
|
if (state instanceof Dispenser) {
|
||||||
|
for (ItemStack stack : ((Dispenser) state).getInventory()) {
|
||||||
|
if (stack != null && !stack.getType().isAir()) {
|
||||||
|
drops.add(stack);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
private BlockDispenseHandler onBlockDispense() {
|
private BlockDispenseHandler onBlockDispense() {
|
||||||
return (e, dispenser, facedBlock, machine) -> {
|
return (e, dispenser, facedBlock, machine) -> {
|
||||||
if (!hasPermission(dispenser, facedBlock)) {
|
if (!hasPermission(dispenser, facedBlock)) {
|
||||||
@ -79,7 +114,7 @@ public class BlockPlacer extends SlimefunItem {
|
|||||||
Material material = e.getItem().getType();
|
Material material = e.getItem().getType();
|
||||||
|
|
||||||
if (SlimefunTag.SHULKER_BOXES.isTagged(material)) {
|
if (SlimefunTag.SHULKER_BOXES.isTagged(material)) {
|
||||||
/**
|
/*
|
||||||
* Since vanilla Dispensers can already place Shulker boxes,
|
* Since vanilla Dispensers can already place Shulker boxes,
|
||||||
* we simply fallback to the vanilla behaviour.
|
* we simply fallback to the vanilla behaviour.
|
||||||
*/
|
*/
|
||||||
@ -89,7 +124,7 @@ public class BlockPlacer extends SlimefunItem {
|
|||||||
e.setCancelled(true);
|
e.setCancelled(true);
|
||||||
|
|
||||||
if (!material.isBlock() || SlimefunTag.BLOCK_PLACER_IGNORED_MATERIALS.isTagged(material)) {
|
if (!material.isBlock() || SlimefunTag.BLOCK_PLACER_IGNORED_MATERIALS.isTagged(material)) {
|
||||||
/**
|
/*
|
||||||
* Some materials cannot be reliably placed, like beds,
|
* Some materials cannot be reliably placed, like beds,
|
||||||
* it would look kinda wonky, so we just ignore these altogether.
|
* it would look kinda wonky, so we just ignore these altogether.
|
||||||
* The event has already been cancelled too, so they won't drop.
|
* The event has already been cancelled too, so they won't drop.
|
||||||
@ -97,7 +132,7 @@ public class BlockPlacer extends SlimefunItem {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (facedBlock.isEmpty() && !isBlacklisted(material) && dispenser.getInventory().getViewers().isEmpty()) {
|
if (facedBlock.isEmpty() && isAllowed(material) && dispenser.getInventory().getViewers().isEmpty()) {
|
||||||
SlimefunItem item = SlimefunItem.getByItem(e.getItem());
|
SlimefunItem item = SlimefunItem.getByItem(e.getItem());
|
||||||
|
|
||||||
if (item != null) {
|
if (item != null) {
|
||||||
@ -123,11 +158,12 @@ public class BlockPlacer extends SlimefunItem {
|
|||||||
*
|
*
|
||||||
* @return Whether this action is permitted or not
|
* @return Whether this action is permitted or not
|
||||||
*/
|
*/
|
||||||
|
@ParametersAreNonnullByDefault
|
||||||
private boolean hasPermission(Dispenser dispenser, Block target) {
|
private boolean hasPermission(Dispenser dispenser, Block target) {
|
||||||
String owner = BlockStorage.getLocationInfo(dispenser.getLocation(), "owner");
|
String owner = BlockStorage.getLocationInfo(dispenser.getLocation(), "owner");
|
||||||
|
|
||||||
if (owner == null) {
|
if (owner == null) {
|
||||||
/**
|
/*
|
||||||
* If no owner was set, then we will fallback to the previous behaviour:
|
* If no owner was set, then we will fallback to the previous behaviour:
|
||||||
* Allowing block placers to bypass protection, newly placed Block placers
|
* Allowing block placers to bypass protection, newly placed Block placers
|
||||||
* will respect protection plugins.
|
* will respect protection plugins.
|
||||||
@ -135,20 +171,30 @@ public class BlockPlacer extends SlimefunItem {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get the corresponding OfflinePlayer
|
||||||
OfflinePlayer player = Bukkit.getOfflinePlayer(UUID.fromString(owner));
|
OfflinePlayer player = Bukkit.getOfflinePlayer(UUID.fromString(owner));
|
||||||
return SlimefunPlugin.getProtectionManager().hasPermission(player, target, ProtectableAction.PLACE_BLOCK);
|
return SlimefunPlugin.getProtectionManager().hasPermission(player, target, ProtectableAction.PLACE_BLOCK);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isBlacklisted(Material type) {
|
/**
|
||||||
for (String blockType : blacklist.getValue()) {
|
* This checks if the given {@link Material} is allowed to be placed.
|
||||||
|
*
|
||||||
|
* @param type
|
||||||
|
* The {@link Material} to check
|
||||||
|
*
|
||||||
|
* @return Whether placing this {@link Material} is allowed
|
||||||
|
*/
|
||||||
|
private boolean isAllowed(@Nonnull Material type) {
|
||||||
|
for (String blockType : unplaceableBlocks.getValue()) {
|
||||||
if (type.toString().equals(blockType)) {
|
if (type.toString().equals(blockType)) {
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParametersAreNonnullByDefault
|
||||||
private void placeSlimefunBlock(SlimefunItem sfItem, ItemStack item, Block block, Dispenser dispenser) {
|
private void placeSlimefunBlock(SlimefunItem sfItem, ItemStack item, Block block, Dispenser dispenser) {
|
||||||
BlockPlacerPlaceEvent e = new BlockPlacerPlaceEvent(dispenser.getBlock(), item, block);
|
BlockPlacerPlaceEvent e = new BlockPlacerPlaceEvent(dispenser.getBlock(), item, block);
|
||||||
Bukkit.getPluginManager().callEvent(e);
|
Bukkit.getPluginManager().callEvent(e);
|
||||||
@ -156,40 +202,31 @@ public class BlockPlacer extends SlimefunItem {
|
|||||||
if (!e.isCancelled()) {
|
if (!e.isCancelled()) {
|
||||||
boolean hasItemHandler = sfItem.callItemHandler(BlockPlaceHandler.class, handler -> {
|
boolean hasItemHandler = sfItem.callItemHandler(BlockPlaceHandler.class, handler -> {
|
||||||
if (handler.isBlockPlacerAllowed()) {
|
if (handler.isBlockPlacerAllowed()) {
|
||||||
|
schedulePlacement(block, dispenser.getInventory(), item, () -> {
|
||||||
block.setType(item.getType());
|
block.setType(item.getType());
|
||||||
block.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, item.getType());
|
|
||||||
|
|
||||||
BlockStorage.store(block, sfItem.getId());
|
BlockStorage.store(block, sfItem.getId());
|
||||||
handler.onBlockPlacerPlace(e);
|
|
||||||
|
|
||||||
if (dispenser.getInventory().containsAtLeast(item, 2)) {
|
handler.onBlockPlacerPlace(e);
|
||||||
dispenser.getInventory().removeItem(new CustomItem(item, 1));
|
});
|
||||||
} else {
|
|
||||||
SlimefunPlugin.runSync(() -> dispenser.getInventory().removeItem(item), 2L);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!hasItemHandler) {
|
if (!hasItemHandler) {
|
||||||
|
schedulePlacement(block, dispenser.getInventory(), item, () -> {
|
||||||
block.setType(item.getType());
|
block.setType(item.getType());
|
||||||
block.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, item.getType());
|
|
||||||
|
|
||||||
BlockStorage.store(block, sfItem.getId());
|
BlockStorage.store(block, sfItem.getId());
|
||||||
|
});
|
||||||
if (dispenser.getInventory().containsAtLeast(item, 2)) {
|
|
||||||
dispenser.getInventory().removeItem(new CustomItem(item, 1));
|
|
||||||
} else {
|
|
||||||
SlimefunPlugin.runSync(() -> dispenser.getInventory().removeItem(item), 2L);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ParametersAreNonnullByDefault
|
||||||
private void placeBlock(ItemStack item, Block facedBlock, Dispenser dispenser) {
|
private void placeBlock(ItemStack item, Block facedBlock, Dispenser dispenser) {
|
||||||
BlockPlacerPlaceEvent e = new BlockPlacerPlaceEvent(dispenser.getBlock(), item, facedBlock);
|
BlockPlacerPlaceEvent e = new BlockPlacerPlaceEvent(dispenser.getBlock(), item, facedBlock);
|
||||||
Bukkit.getPluginManager().callEvent(e);
|
Bukkit.getPluginManager().callEvent(e);
|
||||||
|
|
||||||
if (!e.isCancelled()) {
|
if (!e.isCancelled()) {
|
||||||
|
schedulePlacement(facedBlock, dispenser.getInventory(), item, () -> {
|
||||||
facedBlock.setType(item.getType());
|
facedBlock.setType(item.getType());
|
||||||
|
|
||||||
if (item.hasItemMeta()) {
|
if (item.hasItemMeta()) {
|
||||||
@ -210,14 +247,33 @@ public class BlockPlacer extends SlimefunItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
facedBlock.getWorld().playEffect(facedBlock.getLocation(), Effect.STEP_SOUND, item.getType());
|
|
||||||
|
|
||||||
if (dispenser.getInventory().containsAtLeast(item, 2)) {
|
|
||||||
dispenser.getInventory().removeItem(new CustomItem(item, 1));
|
|
||||||
} else {
|
|
||||||
SlimefunPlugin.runSync(() -> dispenser.getInventory().removeItem(item), 2L);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ParametersAreNonnullByDefault
|
||||||
|
private void schedulePlacement(Block b, Inventory inv, ItemStack item, Runnable runnable) {
|
||||||
|
// We need to delay this due to Dispenser-Inventory synchronization issues in Spigot.
|
||||||
|
SlimefunPlugin.runSync(() -> {
|
||||||
|
// Make sure the Block has not been occupied yet
|
||||||
|
if (b.isEmpty()) {
|
||||||
|
// Only remove 1 item.
|
||||||
|
ItemStack removedItem = item.clone();
|
||||||
|
removedItem.setAmount(1);
|
||||||
|
|
||||||
|
// Play particles
|
||||||
|
b.getWorld().playEffect(b.getLocation(), Effect.STEP_SOUND, item.getType());
|
||||||
|
|
||||||
|
// Make sure the item was actually removed (fixes #2817)
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (inv.removeItem(removedItem).isEmpty()) {
|
||||||
|
runnable.run();
|
||||||
|
}
|
||||||
|
} catch (Exception x) {
|
||||||
|
error("An Exception was thrown while a BlockPlacer was performing its action", x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 2L);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,8 +8,10 @@ import javax.annotation.Nonnull;
|
|||||||
import javax.annotation.ParametersAreNonnullByDefault;
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
|
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.Particle;
|
||||||
import org.bukkit.Sound;
|
import org.bukkit.Sound;
|
||||||
import org.bukkit.Tag;
|
import org.bukkit.Tag;
|
||||||
|
import org.bukkit.World.Environment;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.block.BlockFace;
|
import org.bukkit.block.BlockFace;
|
||||||
import org.bukkit.block.data.Levelled;
|
import org.bukkit.block.data.Levelled;
|
||||||
@ -19,6 +21,7 @@ import org.bukkit.inventory.ItemStack;
|
|||||||
|
|
||||||
import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction;
|
import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction;
|
||||||
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
|
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
|
||||||
|
import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting;
|
||||||
import io.github.thebusybiscuit.slimefun4.core.attributes.RecipeDisplayItem;
|
import io.github.thebusybiscuit.slimefun4.core.attributes.RecipeDisplayItem;
|
||||||
import io.github.thebusybiscuit.slimefun4.core.handlers.BlockUseHandler;
|
import io.github.thebusybiscuit.slimefun4.core.handlers.BlockUseHandler;
|
||||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||||
@ -30,14 +33,26 @@ import me.mrCookieSlime.Slimefun.Objects.Category;
|
|||||||
import me.mrCookieSlime.Slimefun.api.BlockStorage;
|
import me.mrCookieSlime.Slimefun.api.BlockStorage;
|
||||||
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link Crucible} is a machine which turns blocks into liquids.
|
||||||
|
* It is a very reliable source of lava and water.
|
||||||
|
* The liquids will accumulate over time above the machine.
|
||||||
|
*
|
||||||
|
* @author TheBusyBiscuit
|
||||||
|
* @author Sfiguz7
|
||||||
|
*
|
||||||
|
*/
|
||||||
public class Crucible extends SimpleSlimefunItem<BlockUseHandler> implements RecipeDisplayItem {
|
public class Crucible extends SimpleSlimefunItem<BlockUseHandler> implements RecipeDisplayItem {
|
||||||
|
|
||||||
|
private final ItemSetting<Boolean> allowWaterInNether = new ItemSetting<>("allow-water-in-nether", false);
|
||||||
private final List<ItemStack> recipes;
|
private final List<ItemStack> recipes;
|
||||||
|
|
||||||
|
@ParametersAreNonnullByDefault
|
||||||
public Crucible(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
public Crucible(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
||||||
super(category, item, recipeType, recipe);
|
super(category, item, recipeType, recipe);
|
||||||
|
|
||||||
recipes = getMachineRecipes();
|
recipes = getMachineRecipes();
|
||||||
|
addItemSetting(allowWaterInNether);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -45,6 +60,7 @@ public class Crucible extends SimpleSlimefunItem<BlockUseHandler> implements Rec
|
|||||||
return recipes;
|
return recipes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
private List<ItemStack> getMachineRecipes() {
|
private List<ItemStack> getMachineRecipes() {
|
||||||
List<ItemStack> items = new LinkedList<>();
|
List<ItemStack> items = new LinkedList<>();
|
||||||
|
|
||||||
@ -113,11 +129,11 @@ public class Crucible extends SimpleSlimefunItem<BlockUseHandler> implements Rec
|
|||||||
@ParametersAreNonnullByDefault
|
@ParametersAreNonnullByDefault
|
||||||
private boolean craft(Player p, ItemStack input) {
|
private boolean craft(Player p, ItemStack input) {
|
||||||
for (int i = 0; i < recipes.size(); i += 2) {
|
for (int i = 0; i < recipes.size(); i += 2) {
|
||||||
ItemStack convert = recipes.get(i);
|
ItemStack catalyst = recipes.get(i);
|
||||||
|
|
||||||
if (SlimefunUtils.isItemSimilar(input, convert, true)) {
|
if (SlimefunUtils.isItemSimilar(input, catalyst, true)) {
|
||||||
ItemStack removing = input.clone();
|
ItemStack removing = input.clone();
|
||||||
removing.setAmount(convert.getAmount());
|
removing.setAmount(catalyst.getAmount());
|
||||||
p.getInventory().removeItem(removing);
|
p.getInventory().removeItem(removing);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -127,15 +143,31 @@ public class Crucible extends SimpleSlimefunItem<BlockUseHandler> implements Rec
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generateLiquid(@Nonnull Block block, boolean water) {
|
/**
|
||||||
if (block.getType() == (water ? Material.WATER : Material.LAVA)) {
|
* This method starts the process of generating liquids.
|
||||||
addLiquidLevel(block, water);
|
*
|
||||||
} else if (block.getType() == (water ? Material.LAVA : Material.WATER)) {
|
* @param block
|
||||||
|
* The {@link Block} where to generate the liquid
|
||||||
|
* @param isWater
|
||||||
|
* Whether we generate water or lava.
|
||||||
|
*/
|
||||||
|
private void generateLiquid(@Nonnull Block block, boolean isWater) {
|
||||||
|
// Fixes #2877 - If water in the nether is disabled, abort and play an effect.
|
||||||
|
if (isWater && block.getWorld().getEnvironment() == Environment.NETHER && !allowWaterInNether.getValue()) {
|
||||||
|
// We will still consume the items but won't generate water in the Nether.
|
||||||
|
block.getWorld().spawnParticle(Particle.SMOKE_NORMAL, block.getLocation().add(0.5, 0.5, 0.5), 4);
|
||||||
|
block.getWorld().playSound(block.getLocation(), Sound.BLOCK_LAVA_EXTINGUISH, 1F, 1F);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (block.getType() == (isWater ? Material.WATER : Material.LAVA)) {
|
||||||
|
addLiquidLevel(block, isWater);
|
||||||
|
} else if (block.getType() == (isWater ? Material.LAVA : Material.WATER)) {
|
||||||
int level = ((Levelled) block.getBlockData()).getLevel();
|
int level = ((Levelled) block.getBlockData()).getLevel();
|
||||||
block.setType(level == 0 || level == 8 ? Material.OBSIDIAN : Material.STONE);
|
block.setType(level == 0 || level == 8 ? Material.OBSIDIAN : Material.STONE);
|
||||||
block.getWorld().playSound(block.getLocation(), Sound.BLOCK_LAVA_EXTINGUISH, 1F, 1F);
|
block.getWorld().playSound(block.getLocation(), Sound.BLOCK_LAVA_EXTINGUISH, 1F, 1F);
|
||||||
} else {
|
} else {
|
||||||
SlimefunPlugin.runSync(() -> placeLiquid(block, water), 50L);
|
SlimefunPlugin.runSync(() -> placeLiquid(block, isWater), 50L);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
package io.github.thebusybiscuit.slimefun4.implementation.items.blocks;
|
package io.github.thebusybiscuit.slimefun4.implementation.items.blocks;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
|
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
@ -16,6 +19,7 @@ import io.github.thebusybiscuit.slimefun4.core.handlers.BlockBreakHandler;
|
|||||||
import io.github.thebusybiscuit.slimefun4.core.handlers.BlockPlaceHandler;
|
import io.github.thebusybiscuit.slimefun4.core.handlers.BlockPlaceHandler;
|
||||||
import io.github.thebusybiscuit.slimefun4.core.handlers.BlockUseHandler;
|
import io.github.thebusybiscuit.slimefun4.core.handlers.BlockUseHandler;
|
||||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||||
|
import io.github.thebusybiscuit.slimefun4.implementation.handlers.SimpleBlockBreakHandler;
|
||||||
import io.github.thebusybiscuit.slimefun4.utils.ChatUtils;
|
import io.github.thebusybiscuit.slimefun4.utils.ChatUtils;
|
||||||
import io.github.thebusybiscuit.slimefun4.utils.NumberUtils;
|
import io.github.thebusybiscuit.slimefun4.utils.NumberUtils;
|
||||||
import io.github.thebusybiscuit.slimefun4.utils.holograms.SimpleHologram;
|
import io.github.thebusybiscuit.slimefun4.utils.holograms.SimpleHologram;
|
||||||
@ -30,12 +34,14 @@ public class HologramProjector extends SlimefunItem implements HologramOwner {
|
|||||||
|
|
||||||
private static final String OFFSET_PARAMETER = "offset";
|
private static final String OFFSET_PARAMETER = "offset";
|
||||||
|
|
||||||
|
@ParametersAreNonnullByDefault
|
||||||
public HologramProjector(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe, ItemStack recipeOutput) {
|
public HologramProjector(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe, ItemStack recipeOutput) {
|
||||||
super(category, item, recipeType, recipe, recipeOutput);
|
super(category, item, recipeType, recipe, recipeOutput);
|
||||||
|
|
||||||
addItemHandler(onPlace(), onRightClick(), onBreak());
|
addItemHandler(onPlace(), onRightClick(), onBreak());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
private BlockPlaceHandler onPlace() {
|
private BlockPlaceHandler onPlace() {
|
||||||
return new BlockPlaceHandler(false) {
|
return new BlockPlaceHandler(false) {
|
||||||
|
|
||||||
@ -52,13 +58,18 @@ public class HologramProjector extends SlimefunItem implements HologramOwner {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
private BlockBreakHandler onBreak() {
|
private BlockBreakHandler onBreak() {
|
||||||
return (e, item, fortune, drops) -> {
|
return new SimpleBlockBreakHandler() {
|
||||||
remove(e.getBlock());
|
|
||||||
return true;
|
@Override
|
||||||
|
public void onBlockBreak(@Nonnull Block b) {
|
||||||
|
remove(b);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
public BlockUseHandler onRightClick() {
|
public BlockUseHandler onRightClick() {
|
||||||
return e -> {
|
return e -> {
|
||||||
e.cancel();
|
e.cancel();
|
||||||
@ -72,7 +83,7 @@ public class HologramProjector extends SlimefunItem implements HologramOwner {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void openEditor(Player p, Block projector) {
|
private static void openEditor(@Nonnull Player p, @Nonnull Block projector) {
|
||||||
ChestMenu menu = new ChestMenu(SlimefunPlugin.getLocalization().getMessage(p, "machines.HOLOGRAM_PROJECTOR.inventory-title"));
|
ChestMenu menu = new ChestMenu(SlimefunPlugin.getLocalization().getMessage(p, "machines.HOLOGRAM_PROJECTOR.inventory-title"));
|
||||||
|
|
||||||
menu.addItem(0, new CustomItem(Material.NAME_TAG, "&7Text &e(Click to edit)", "", "&r" + ChatColors.color(BlockStorage.getLocationInfo(projector.getLocation(), "text"))));
|
menu.addItem(0, new CustomItem(Material.NAME_TAG, "&7Text &e(Click to edit)", "", "&r" + ChatColors.color(BlockStorage.getLocationInfo(projector.getLocation(), "text"))));
|
||||||
@ -105,7 +116,7 @@ public class HologramProjector extends SlimefunItem implements HologramOwner {
|
|||||||
menu.open(p);
|
menu.open(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ArmorStand getArmorStand(Block projector, boolean createIfNoneExists) {
|
private static ArmorStand getArmorStand(@Nonnull Block projector, boolean createIfNoneExists) {
|
||||||
String nametag = BlockStorage.getLocationInfo(projector.getLocation(), "text");
|
String nametag = BlockStorage.getLocationInfo(projector.getLocation(), "text");
|
||||||
double offset = Double.parseDouble(BlockStorage.getLocationInfo(projector.getLocation(), OFFSET_PARAMETER));
|
double offset = Double.parseDouble(BlockStorage.getLocationInfo(projector.getLocation(), OFFSET_PARAMETER));
|
||||||
Location l = new Location(projector.getWorld(), projector.getX() + 0.5, projector.getY() + offset, projector.getZ() + 0.5);
|
Location l = new Location(projector.getWorld(), projector.getX() + 0.5, projector.getY() + offset, projector.getZ() + 0.5);
|
||||||
@ -129,7 +140,7 @@ public class HologramProjector extends SlimefunItem implements HologramOwner {
|
|||||||
return hologram;
|
return hologram;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void remove(Block b) {
|
private static void remove(@Nonnull Block b) {
|
||||||
ArmorStand hologram = getArmorStand(b, false);
|
ArmorStand hologram = getArmorStand(b, false);
|
||||||
|
|
||||||
if (hologram != null) {
|
if (hologram != null) {
|
||||||
|
@ -0,0 +1,62 @@
|
|||||||
|
package io.github.thebusybiscuit.slimefun4.implementation.items.blocks;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
|
|
||||||
|
import org.bukkit.block.Block;
|
||||||
|
import org.bukkit.block.BlockState;
|
||||||
|
import org.bukkit.block.Dropper;
|
||||||
|
import org.bukkit.event.block.BlockBreakEvent;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
import io.github.thebusybiscuit.slimefun4.core.handlers.BlockBreakHandler;
|
||||||
|
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
|
||||||
|
import io.github.thebusybiscuit.slimefun4.implementation.items.multiblocks.Smeltery;
|
||||||
|
import io.papermc.lib.PaperLib;
|
||||||
|
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
|
||||||
|
import me.mrCookieSlime.Slimefun.Objects.Category;
|
||||||
|
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link IgnitionChamber} is used to re-ignite a {@link Smeltery}.
|
||||||
|
*
|
||||||
|
* @author TheBusyBiscuit
|
||||||
|
*
|
||||||
|
* @see Smeltery
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class IgnitionChamber extends SimpleSlimefunItem<BlockBreakHandler> {
|
||||||
|
|
||||||
|
@ParametersAreNonnullByDefault
|
||||||
|
public IgnitionChamber(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
||||||
|
super(category, item, recipeType, recipe);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockBreakHandler getItemHandler() {
|
||||||
|
/*
|
||||||
|
* Explosions don't need explicit handling here.
|
||||||
|
* The default of "destroy the dispenser and drop the contents" is
|
||||||
|
* fine for our purposes already.
|
||||||
|
*/
|
||||||
|
return new BlockBreakHandler(false, true) {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPlayerBreak(BlockBreakEvent e, ItemStack item, List<ItemStack> drops) {
|
||||||
|
// Fixes #2856 - Manually drop inventory contents
|
||||||
|
Block b = e.getBlock();
|
||||||
|
BlockState state = PaperLib.getBlockState(b, false).getState();
|
||||||
|
|
||||||
|
if (state instanceof Dropper) {
|
||||||
|
for (ItemStack stack : ((Dropper) state).getInventory()) {
|
||||||
|
if (stack != null && !stack.getType().isAir()) {
|
||||||
|
drops.add(stack);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,63 @@
|
|||||||
|
package io.github.thebusybiscuit.slimefun4.implementation.items.blocks;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
|
|
||||||
|
import org.bukkit.block.Block;
|
||||||
|
import org.bukkit.block.BlockState;
|
||||||
|
import org.bukkit.block.Chest;
|
||||||
|
import org.bukkit.event.block.BlockBreakEvent;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
import io.github.thebusybiscuit.slimefun4.core.handlers.BlockBreakHandler;
|
||||||
|
import io.github.thebusybiscuit.slimefun4.core.multiblocks.MultiBlockMachine;
|
||||||
|
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
|
||||||
|
import io.papermc.lib.PaperLib;
|
||||||
|
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
|
||||||
|
import me.mrCookieSlime.Slimefun.Objects.Category;
|
||||||
|
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link OutputChest} can be used to capture the output items from a {@link MultiBlockMachine}.
|
||||||
|
*
|
||||||
|
* @author TheBusyBiscuit
|
||||||
|
*
|
||||||
|
* @see MultiBlockMachine
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class OutputChest extends SimpleSlimefunItem<BlockBreakHandler> {
|
||||||
|
|
||||||
|
@ParametersAreNonnullByDefault
|
||||||
|
public OutputChest(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
||||||
|
super(category, item, recipeType, recipe);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockBreakHandler getItemHandler() {
|
||||||
|
/*
|
||||||
|
* Explosions don't need explicit handling here.
|
||||||
|
* The default of "destroy the chest and drop the contents" is
|
||||||
|
* fine for our purposes already.
|
||||||
|
*/
|
||||||
|
return new BlockBreakHandler(false, true) {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPlayerBreak(BlockBreakEvent e, ItemStack item, List<ItemStack> drops) {
|
||||||
|
// Fixes #2849 - Manually drop inventory contents
|
||||||
|
Block b = e.getBlock();
|
||||||
|
BlockState state = PaperLib.getBlockState(b, false).getState();
|
||||||
|
|
||||||
|
if (state instanceof Chest) {
|
||||||
|
// Fixes #2851 - Only drop the actual BlockInventory
|
||||||
|
for (ItemStack stack : ((Chest) state).getBlockInventory()) {
|
||||||
|
if (stack != null && !stack.getType().isAir()) {
|
||||||
|
drops.add(stack);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -11,7 +11,9 @@ import org.bukkit.event.block.BlockPlaceEvent;
|
|||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
|
import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
|
||||||
|
import io.github.thebusybiscuit.slimefun4.core.handlers.BlockBreakHandler;
|
||||||
import io.github.thebusybiscuit.slimefun4.core.networks.cargo.CargoNet;
|
import io.github.thebusybiscuit.slimefun4.core.networks.cargo.CargoNet;
|
||||||
|
import io.github.thebusybiscuit.slimefun4.implementation.handlers.SimpleBlockBreakHandler;
|
||||||
import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils;
|
import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils;
|
||||||
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
|
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
|
||||||
import me.mrCookieSlime.Slimefun.Objects.Category;
|
import me.mrCookieSlime.Slimefun.Objects.Category;
|
||||||
@ -39,15 +41,27 @@ abstract class AbstractFilterNode extends AbstractCargoNode {
|
|||||||
public AbstractFilterNode(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe, @Nullable ItemStack recipeOutput) {
|
public AbstractFilterNode(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe, @Nullable ItemStack recipeOutput) {
|
||||||
super(category, item, recipeType, recipe, recipeOutput);
|
super(category, item, recipeType, recipe, recipeOutput);
|
||||||
|
|
||||||
registerBlockHandler(getId(), (p, b, stack, reason) -> {
|
addItemHandler(onBreak());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasItemFilter() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
private BlockBreakHandler onBreak() {
|
||||||
|
return new SimpleBlockBreakHandler() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBlockBreak(@Nonnull Block b) {
|
||||||
BlockMenu inv = BlockStorage.getInventory(b);
|
BlockMenu inv = BlockStorage.getInventory(b);
|
||||||
|
|
||||||
if (inv != null) {
|
if (inv != null) {
|
||||||
inv.dropItems(b.getLocation(), SLOTS);
|
inv.dropItems(b.getLocation(), SLOTS);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return true;
|
};
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
|
@ -2,6 +2,7 @@ package io.github.thebusybiscuit.slimefun4.implementation.items.cargo;
|
|||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.ParametersAreNonnullByDefault;
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
|
|
||||||
import org.bukkit.ChatColor;
|
import org.bukkit.ChatColor;
|
||||||
@ -11,8 +12,10 @@ import org.bukkit.inventory.ItemStack;
|
|||||||
|
|
||||||
import io.github.thebusybiscuit.slimefun4.api.events.PlayerRightClickEvent;
|
import io.github.thebusybiscuit.slimefun4.api.events.PlayerRightClickEvent;
|
||||||
import io.github.thebusybiscuit.slimefun4.core.attributes.HologramOwner;
|
import io.github.thebusybiscuit.slimefun4.core.attributes.HologramOwner;
|
||||||
|
import io.github.thebusybiscuit.slimefun4.core.handlers.BlockBreakHandler;
|
||||||
import io.github.thebusybiscuit.slimefun4.core.handlers.BlockUseHandler;
|
import io.github.thebusybiscuit.slimefun4.core.handlers.BlockUseHandler;
|
||||||
import io.github.thebusybiscuit.slimefun4.core.networks.cargo.CargoNet;
|
import io.github.thebusybiscuit.slimefun4.core.networks.cargo.CargoNet;
|
||||||
|
import io.github.thebusybiscuit.slimefun4.implementation.handlers.SimpleBlockBreakHandler;
|
||||||
import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config;
|
import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config;
|
||||||
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
|
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
|
||||||
import me.mrCookieSlime.Slimefun.Objects.Category;
|
import me.mrCookieSlime.Slimefun.Objects.Category;
|
||||||
@ -27,10 +30,18 @@ public class CargoManager extends SlimefunItem implements HologramOwner {
|
|||||||
public CargoManager(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
public CargoManager(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
||||||
super(category, item, recipeType, recipe);
|
super(category, item, recipeType, recipe);
|
||||||
|
|
||||||
registerBlockHandler(getId(), (p, b, tool, reason) -> {
|
addItemHandler(onBreak());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
private BlockBreakHandler onBreak() {
|
||||||
|
return new SimpleBlockBreakHandler() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBlockBreak(@Nonnull Block b) {
|
||||||
removeHologram(b);
|
removeHologram(b);
|
||||||
return true;
|
}
|
||||||
});
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -14,7 +14,6 @@ import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
|
|||||||
* @author TheBusyBiscuit
|
* @author TheBusyBiscuit
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@FunctionalInterface
|
|
||||||
public interface CargoNode {
|
public interface CargoNode {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -27,4 +26,11 @@ public interface CargoNode {
|
|||||||
*/
|
*/
|
||||||
int getSelectedChannel(@Nonnull Block b);
|
int getSelectedChannel(@Nonnull Block b);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This returns whether this {@link CargoNode} has item filtering capabilities.
|
||||||
|
*
|
||||||
|
* @return Whether this {@link CargoNode} can filter items
|
||||||
|
*/
|
||||||
|
boolean hasItemFilter();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package io.github.thebusybiscuit.slimefun4.implementation.items.cargo;
|
package io.github.thebusybiscuit.slimefun4.implementation.items.cargo;
|
||||||
|
|
||||||
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
|
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
@ -18,10 +20,16 @@ public class CargoOutputNode extends AbstractCargoNode {
|
|||||||
|
|
||||||
private static final int[] BORDER = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26 };
|
private static final int[] BORDER = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26 };
|
||||||
|
|
||||||
|
@ParametersAreNonnullByDefault
|
||||||
public CargoOutputNode(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe, ItemStack recipeOutput) {
|
public CargoOutputNode(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe, ItemStack recipeOutput) {
|
||||||
super(category, item, recipeType, recipe, recipeOutput);
|
super(category, item, recipeType, recipe, recipeOutput);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasItemFilter() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onPlace(BlockPlaceEvent e) {
|
protected void onPlace(BlockPlaceEvent e) {
|
||||||
// We only require the default values
|
// We only require the default values
|
||||||
|
@ -12,9 +12,11 @@ import org.bukkit.inventory.ItemStack;
|
|||||||
|
|
||||||
import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
|
import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
|
||||||
import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction;
|
import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction;
|
||||||
|
import io.github.thebusybiscuit.slimefun4.core.handlers.BlockBreakHandler;
|
||||||
import io.github.thebusybiscuit.slimefun4.core.networks.cargo.CargoNet;
|
import io.github.thebusybiscuit.slimefun4.core.networks.cargo.CargoNet;
|
||||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
|
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
|
||||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||||
|
import io.github.thebusybiscuit.slimefun4.implementation.handlers.SimpleBlockBreakHandler;
|
||||||
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.reactors.Reactor;
|
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.reactors.Reactor;
|
||||||
import io.github.thebusybiscuit.slimefun4.implementation.items.misc.CoolantCell;
|
import io.github.thebusybiscuit.slimefun4.implementation.items.misc.CoolantCell;
|
||||||
import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils;
|
import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils;
|
||||||
@ -50,6 +52,8 @@ public class ReactorAccessPort extends SlimefunItem {
|
|||||||
public ReactorAccessPort(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
public ReactorAccessPort(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
||||||
super(category, item, recipeType, recipe);
|
super(category, item, recipeType, recipe);
|
||||||
|
|
||||||
|
addItemHandler(onBreak());
|
||||||
|
|
||||||
new BlockMenuPreset(getId(), "&2Reactor Access Port") {
|
new BlockMenuPreset(getId(), "&2Reactor Access Port") {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -108,8 +112,14 @@ public class ReactorAccessPort extends SlimefunItem {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
registerBlockHandler(getId(), (p, b, tool, reason) -> {
|
@Nonnull
|
||||||
|
private BlockBreakHandler onBreak() {
|
||||||
|
return new SimpleBlockBreakHandler() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBlockBreak(@Nonnull Block b) {
|
||||||
BlockMenu inv = BlockStorage.getInventory(b);
|
BlockMenu inv = BlockStorage.getInventory(b);
|
||||||
|
|
||||||
if (inv != null) {
|
if (inv != null) {
|
||||||
@ -117,9 +127,8 @@ public class ReactorAccessPort extends SlimefunItem {
|
|||||||
inv.dropItems(b.getLocation(), getCoolantSlots());
|
inv.dropItems(b.getLocation(), getCoolantSlots());
|
||||||
inv.dropItems(b.getLocation(), getOutputSlots());
|
inv.dropItems(b.getLocation(), getOutputSlots());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return true;
|
};
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void constructMenu(@Nonnull BlockMenuPreset preset) {
|
private void constructMenu(@Nonnull BlockMenuPreset preset) {
|
||||||
|
@ -9,8 +9,10 @@ import org.bukkit.inventory.ItemStack;
|
|||||||
|
|
||||||
import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetComponent;
|
import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetComponent;
|
||||||
import io.github.thebusybiscuit.slimefun4.core.attributes.HologramOwner;
|
import io.github.thebusybiscuit.slimefun4.core.attributes.HologramOwner;
|
||||||
|
import io.github.thebusybiscuit.slimefun4.core.handlers.BlockBreakHandler;
|
||||||
import io.github.thebusybiscuit.slimefun4.core.handlers.BlockPlaceHandler;
|
import io.github.thebusybiscuit.slimefun4.core.handlers.BlockPlaceHandler;
|
||||||
import io.github.thebusybiscuit.slimefun4.core.networks.energy.EnergyNet;
|
import io.github.thebusybiscuit.slimefun4.core.networks.energy.EnergyNet;
|
||||||
|
import io.github.thebusybiscuit.slimefun4.implementation.handlers.SimpleBlockBreakHandler;
|
||||||
import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config;
|
import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config;
|
||||||
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
|
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
|
||||||
import me.mrCookieSlime.Slimefun.Objects.Category;
|
import me.mrCookieSlime.Slimefun.Objects.Category;
|
||||||
@ -34,10 +36,18 @@ public class EnergyRegulator extends SlimefunItem implements HologramOwner {
|
|||||||
public EnergyRegulator(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
public EnergyRegulator(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
||||||
super(category, item, recipeType, recipe);
|
super(category, item, recipeType, recipe);
|
||||||
|
|
||||||
SlimefunItem.registerBlockHandler(getId(), (p, b, stack, reason) -> {
|
addItemHandler(onBreak());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
private BlockBreakHandler onBreak() {
|
||||||
|
return new SimpleBlockBreakHandler() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBlockBreak(@Nonnull Block b) {
|
||||||
removeHologram(b);
|
removeHologram(b);
|
||||||
return true;
|
}
|
||||||
});
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
|
@ -2,84 +2,25 @@ package io.github.thebusybiscuit.slimefun4.implementation.items.electric.machine
|
|||||||
|
|
||||||
import javax.annotation.ParametersAreNonnullByDefault;
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.block.Block;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
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.networks.energy.EnergyNetComponentType;
|
|
||||||
import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils;
|
|
||||||
import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config;
|
|
||||||
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
|
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
|
||||||
import me.mrCookieSlime.Slimefun.Objects.Category;
|
import me.mrCookieSlime.Slimefun.Objects.Category;
|
||||||
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
|
|
||||||
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.interfaces.InventoryBlock;
|
|
||||||
import me.mrCookieSlime.Slimefun.Objects.handlers.BlockTicker;
|
|
||||||
import me.mrCookieSlime.Slimefun.api.BlockStorage;
|
|
||||||
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
||||||
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu;
|
|
||||||
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset;
|
|
||||||
|
|
||||||
public abstract class AbstractGrowthAccelerator extends SlimefunItem implements InventoryBlock, EnergyNetComponent {
|
/**
|
||||||
|
* This has been moved.
|
||||||
private static final int[] BORDER = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26 };
|
*
|
||||||
|
* @deprecated Moved to
|
||||||
|
* {@link io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.accelerators.AbstractGrowthAccelerator}
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public abstract class AbstractGrowthAccelerator extends io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.accelerators.AbstractGrowthAccelerator {
|
||||||
|
|
||||||
@ParametersAreNonnullByDefault
|
@ParametersAreNonnullByDefault
|
||||||
public AbstractGrowthAccelerator(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
public AbstractGrowthAccelerator(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
||||||
super(category, item, recipeType, recipe);
|
super(category, item, recipeType, recipe);
|
||||||
|
|
||||||
createPreset(this, this::constructMenu);
|
|
||||||
|
|
||||||
registerBlockHandler(getId(), (p, b, tool, reason) -> {
|
|
||||||
BlockMenu inv = BlockStorage.getInventory(b);
|
|
||||||
|
|
||||||
if (inv != null) {
|
|
||||||
inv.dropItems(b.getLocation(), getInputSlots());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void constructMenu(BlockMenuPreset preset) {
|
|
||||||
for (int i : BORDER) {
|
|
||||||
preset.addItem(i, new CustomItem(Material.CYAN_STAINED_GLASS_PANE, " "), ChestMenuUtils.getEmptyClickHandler());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EnergyNetComponentType getEnergyComponentType() {
|
|
||||||
return EnergyNetComponentType.CONSUMER;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int[] getInputSlots() {
|
|
||||||
return new int[] { 10, 11, 12, 13, 14, 15, 16 };
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int[] getOutputSlots() {
|
|
||||||
return new int[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void preRegister() {
|
|
||||||
super.preRegister();
|
|
||||||
addItemHandler(new BlockTicker() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void tick(Block b, SlimefunItem sf, Config data) {
|
|
||||||
AbstractGrowthAccelerator.this.tick(b);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isSynchronized() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract void tick(Block b);
|
|
||||||
|
|
||||||
}
|
}
|
@ -1,140 +1,26 @@
|
|||||||
package io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines;
|
package io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines;
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
import javax.annotation.ParametersAreNonnullByDefault;
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.enchantments.Enchantment;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.inventory.meta.EnchantmentStorageMeta;
|
|
||||||
import org.bukkit.inventory.meta.ItemMeta;
|
|
||||||
import org.bukkit.inventory.meta.Repairable;
|
|
||||||
|
|
||||||
import io.github.thebusybiscuit.cscorelib2.inventory.InvUtils;
|
|
||||||
import io.github.thebusybiscuit.slimefun4.api.events.AutoDisenchantEvent;
|
|
||||||
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
|
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
|
||||||
import me.mrCookieSlime.Slimefun.Objects.Category;
|
import me.mrCookieSlime.Slimefun.Objects.Category;
|
||||||
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
|
|
||||||
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AContainer;
|
|
||||||
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.MachineRecipe;
|
|
||||||
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
||||||
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@link AutoDisenchanter}, in contrast to the {@link AutoEnchanter}, removes
|
* This has been moved.
|
||||||
* {@link Enchantment Enchantments} from a given {@link ItemStack} and transfers them
|
|
||||||
* to a book.
|
|
||||||
*
|
*
|
||||||
* @author TheBusyBiscuit
|
* @deprecated Moved to
|
||||||
* @author Walshy
|
* {@link io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.enchanting.AutoDisenchanter}
|
||||||
* @author poma123
|
|
||||||
*
|
|
||||||
* @see AutoEnchanter
|
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class AutoDisenchanter extends AContainer {
|
@Deprecated
|
||||||
|
public class AutoDisenchanter extends io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.enchanting.AutoEnchanter {
|
||||||
|
|
||||||
@ParametersAreNonnullByDefault
|
@ParametersAreNonnullByDefault
|
||||||
public AutoDisenchanter(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
public AutoDisenchanter(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
||||||
super(category, item, recipeType, recipe);
|
super(category, item, recipeType, recipe);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ItemStack getProgressBar() {
|
|
||||||
return new ItemStack(Material.DIAMOND_CHESTPLATE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected MachineRecipe findNextRecipe(BlockMenu menu) {
|
|
||||||
Map<Enchantment, Integer> enchantments = new HashMap<>();
|
|
||||||
|
|
||||||
for (int slot : getInputSlots()) {
|
|
||||||
ItemStack item = menu.getItemInSlot(slot);
|
|
||||||
|
|
||||||
if (!isDisenchantable(item)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
AutoDisenchantEvent event = new AutoDisenchantEvent(item);
|
|
||||||
Bukkit.getPluginManager().callEvent(event);
|
|
||||||
|
|
||||||
if (event.isCancelled()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
ItemStack target = menu.getItemInSlot(slot == getInputSlots()[0] ? getInputSlots()[1] : getInputSlots()[0]);
|
|
||||||
|
|
||||||
// Disenchanting
|
|
||||||
if (target != null && target.getType() == Material.BOOK) {
|
|
||||||
int amount = 0;
|
|
||||||
|
|
||||||
for (Map.Entry<Enchantment, Integer> entry : item.getEnchantments().entrySet()) {
|
|
||||||
enchantments.put(entry.getKey(), entry.getValue());
|
|
||||||
amount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (amount > 0) {
|
|
||||||
ItemStack disenchantedItem = item.clone();
|
|
||||||
disenchantedItem.setAmount(1);
|
|
||||||
|
|
||||||
ItemStack book = new ItemStack(Material.ENCHANTED_BOOK);
|
|
||||||
transferEnchantments(disenchantedItem, book, enchantments);
|
|
||||||
|
|
||||||
MachineRecipe recipe = new MachineRecipe(90 * amount / this.getSpeed(), new ItemStack[] { target, item }, new ItemStack[] { disenchantedItem, book });
|
|
||||||
|
|
||||||
if (!InvUtils.fitAll(menu.toInventory(), recipe.getOutput(), getOutputSlots())) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int inputSlot : getInputSlots()) {
|
|
||||||
menu.consumeItem(inputSlot);
|
|
||||||
}
|
|
||||||
|
|
||||||
return recipe;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void transferEnchantments(ItemStack item, ItemStack book, Map<Enchantment, Integer> enchantments) {
|
|
||||||
ItemMeta itemMeta = item.getItemMeta();
|
|
||||||
ItemMeta bookMeta = book.getItemMeta();
|
|
||||||
((Repairable) bookMeta).setRepairCost(((Repairable) itemMeta).getRepairCost());
|
|
||||||
((Repairable) itemMeta).setRepairCost(0);
|
|
||||||
item.setItemMeta(itemMeta);
|
|
||||||
book.setItemMeta(bookMeta);
|
|
||||||
|
|
||||||
EnchantmentStorageMeta meta = (EnchantmentStorageMeta) book.getItemMeta();
|
|
||||||
|
|
||||||
for (Map.Entry<Enchantment, Integer> entry : enchantments.entrySet()) {
|
|
||||||
item.removeEnchantment(entry.getKey());
|
|
||||||
meta.addStoredEnchant(entry.getKey(), entry.getValue(), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
book.setItemMeta(meta);
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isDisenchantable(@Nullable ItemStack item) {
|
|
||||||
if (item == null) {
|
|
||||||
return false;
|
|
||||||
} else if (item.getType() != Material.BOOK) {
|
|
||||||
// ^ This stops endless checks of getByItem for books
|
|
||||||
SlimefunItem sfItem = SlimefunItem.getByItem(item);
|
|
||||||
return sfItem == null || sfItem.isDisenchantable();
|
|
||||||
} else {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getMachineIdentifier() {
|
|
||||||
return "AUTO_DISENCHANTER";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
@ -1,102 +1,26 @@
|
|||||||
package io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines;
|
package io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines;
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import javax.annotation.ParametersAreNonnullByDefault;
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.enchantments.Enchantment;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.inventory.meta.EnchantmentStorageMeta;
|
|
||||||
|
|
||||||
import io.github.thebusybiscuit.cscorelib2.inventory.InvUtils;
|
|
||||||
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
|
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
|
||||||
import me.mrCookieSlime.Slimefun.Objects.Category;
|
import me.mrCookieSlime.Slimefun.Objects.Category;
|
||||||
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
|
|
||||||
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AContainer;
|
|
||||||
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.MachineRecipe;
|
|
||||||
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
||||||
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu;
|
|
||||||
|
|
||||||
public class AutoEnchanter extends AContainer {
|
/**
|
||||||
|
* This has been moved.
|
||||||
|
*
|
||||||
|
* @deprecated Moved to
|
||||||
|
* {@link io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.enchanting.AutoEnchanter}
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public class AutoEnchanter extends io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.enchanting.AutoEnchanter {
|
||||||
|
|
||||||
@ParametersAreNonnullByDefault
|
@ParametersAreNonnullByDefault
|
||||||
public AutoEnchanter(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
public AutoEnchanter(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
||||||
super(category, item, recipeType, recipe);
|
super(category, item, recipeType, recipe);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ItemStack getProgressBar() {
|
|
||||||
return new ItemStack(Material.GOLDEN_CHESTPLATE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected MachineRecipe findNextRecipe(BlockMenu menu) {
|
|
||||||
for (int slot : getInputSlots()) {
|
|
||||||
ItemStack target = menu.getItemInSlot(slot == getInputSlots()[0] ? getInputSlots()[1] : getInputSlots()[0]);
|
|
||||||
|
|
||||||
// Check if the item is enchantable
|
|
||||||
if (!isEnchantable(target)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
ItemStack item = menu.getItemInSlot(slot);
|
|
||||||
|
|
||||||
if (item != null && item.getType() == Material.ENCHANTED_BOOK && target != null) {
|
|
||||||
Map<Enchantment, Integer> enchantments = new HashMap<>();
|
|
||||||
int amount = 0;
|
|
||||||
EnchantmentStorageMeta meta = (EnchantmentStorageMeta) item.getItemMeta();
|
|
||||||
|
|
||||||
for (Map.Entry<Enchantment, Integer> e : meta.getStoredEnchants().entrySet()) {
|
|
||||||
if (e.getKey().canEnchantItem(target)) {
|
|
||||||
amount++;
|
|
||||||
enchantments.put(e.getKey(), e.getValue());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (amount > 0) {
|
|
||||||
ItemStack enchantedItem = target.clone();
|
|
||||||
enchantedItem.setAmount(1);
|
|
||||||
|
|
||||||
for (Map.Entry<Enchantment, Integer> entry : enchantments.entrySet()) {
|
|
||||||
enchantedItem.addUnsafeEnchantment(entry.getKey(), entry.getValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
MachineRecipe recipe = new MachineRecipe(75 * amount / this.getSpeed(), new ItemStack[] { target, item }, new ItemStack[] { enchantedItem, new ItemStack(Material.BOOK) });
|
|
||||||
|
|
||||||
if (!InvUtils.fitAll(menu.toInventory(), recipe.getOutput(), getOutputSlots())) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int inputSlot : getInputSlots()) {
|
|
||||||
menu.consumeItem(inputSlot);
|
|
||||||
}
|
|
||||||
|
|
||||||
return recipe;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isEnchantable(ItemStack item) {
|
|
||||||
SlimefunItem sfItem = null;
|
|
||||||
|
|
||||||
// stops endless checks of getByItem for enchanted book stacks.
|
|
||||||
if (item != null && item.getType() != Material.ENCHANTED_BOOK) {
|
|
||||||
sfItem = SlimefunItem.getByItem(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
return sfItem == null || sfItem.isEnchantable();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getMachineIdentifier() {
|
|
||||||
return "AUTO_ENCHANTER";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
@ -7,6 +7,9 @@ import java.util.HashMap;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
|
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
@ -57,10 +60,11 @@ public abstract class AutomatedCraftingChamber extends SlimefunItem implements I
|
|||||||
|
|
||||||
private final Map<String, ItemStack> craftingRecipes = new HashMap<>();
|
private final Map<String, ItemStack> craftingRecipes = new HashMap<>();
|
||||||
|
|
||||||
|
@ParametersAreNonnullByDefault
|
||||||
public AutomatedCraftingChamber(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
public AutomatedCraftingChamber(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
||||||
super(category, item, recipeType, recipe);
|
super(category, item, recipeType, recipe);
|
||||||
|
|
||||||
new BlockMenuPreset(getId(), "&6Automated Crafting Chamber") {
|
new BlockMenuPreset(getId(), "&4Deprecated item. Do not use.") {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init() {
|
public void init() {
|
||||||
@ -94,6 +98,7 @@ public abstract class AutomatedCraftingChamber extends SlimefunItem implements I
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canOpen(Block b, Player p) {
|
public boolean canOpen(Block b, Player p) {
|
||||||
|
p.sendMessage(ChatColor.DARK_RED + "This item has been deprecated. It will be removed soon!");
|
||||||
return p.hasPermission("slimefun.inventory.bypass") || SlimefunPlugin.getProtectionManager().hasPermission(p, b.getLocation(), ProtectableAction.INTERACT_BLOCK);
|
return p.hasPermission("slimefun.inventory.bypass") || SlimefunPlugin.getProtectionManager().hasPermission(p, b.getLocation(), ProtectableAction.INTERACT_BLOCK);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,6 +150,7 @@ public abstract class AutomatedCraftingChamber extends SlimefunItem implements I
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPlayerPlace(BlockPlaceEvent e) {
|
public void onPlayerPlace(BlockPlaceEvent e) {
|
||||||
|
e.getPlayer().sendMessage(ChatColor.DARK_RED + "This item has been deprecated. It will be removed soon!");
|
||||||
BlockStorage.addBlockInfo(e.getBlock(), "enabled", String.valueOf(false));
|
BlockStorage.addBlockInfo(e.getBlock(), "enabled", String.valueOf(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,85 @@
|
|||||||
|
package io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.accelerators;
|
||||||
|
|
||||||
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
|
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.block.Block;
|
||||||
|
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.networks.energy.EnergyNetComponentType;
|
||||||
|
import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils;
|
||||||
|
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.interfaces.InventoryBlock;
|
||||||
|
import me.mrCookieSlime.Slimefun.Objects.handlers.BlockTicker;
|
||||||
|
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 abstract class AbstractGrowthAccelerator extends SlimefunItem implements InventoryBlock, EnergyNetComponent {
|
||||||
|
|
||||||
|
private static final int[] BORDER = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26 };
|
||||||
|
|
||||||
|
@ParametersAreNonnullByDefault
|
||||||
|
public AbstractGrowthAccelerator(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
||||||
|
super(category, item, recipeType, recipe);
|
||||||
|
|
||||||
|
createPreset(this, this::constructMenu);
|
||||||
|
|
||||||
|
registerBlockHandler(getId(), (p, b, tool, reason) -> {
|
||||||
|
BlockMenu inv = BlockStorage.getInventory(b);
|
||||||
|
|
||||||
|
if (inv != null) {
|
||||||
|
inv.dropItems(b.getLocation(), getInputSlots());
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void constructMenu(BlockMenuPreset preset) {
|
||||||
|
for (int i : BORDER) {
|
||||||
|
preset.addItem(i, new CustomItem(Material.CYAN_STAINED_GLASS_PANE, " "), ChestMenuUtils.getEmptyClickHandler());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EnergyNetComponentType getEnergyComponentType() {
|
||||||
|
return EnergyNetComponentType.CONSUMER;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int[] getInputSlots() {
|
||||||
|
return new int[] { 10, 11, 12, 13, 14, 15, 16 };
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int[] getOutputSlots() {
|
||||||
|
return new int[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void preRegister() {
|
||||||
|
super.preRegister();
|
||||||
|
addItemHandler(new BlockTicker() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void tick(Block b, SlimefunItem sf, Config data) {
|
||||||
|
AbstractGrowthAccelerator.this.tick(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isSynchronized() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract void tick(Block b);
|
||||||
|
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines;
|
package io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.accelerators;
|
||||||
|
|
||||||
import org.bukkit.Particle;
|
import org.bukkit.Particle;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
@ -1,4 +1,4 @@
|
|||||||
package io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines;
|
package io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.accelerators;
|
||||||
|
|
||||||
import org.bukkit.Particle;
|
import org.bukkit.Particle;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
@ -1,4 +1,4 @@
|
|||||||
package io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines;
|
package io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.accelerators;
|
||||||
|
|
||||||
import org.bukkit.Particle;
|
import org.bukkit.Particle;
|
||||||
import org.bukkit.Tag;
|
import org.bukkit.Tag;
|
@ -0,0 +1,5 @@
|
|||||||
|
/**
|
||||||
|
* This package contains any electric machines related to growth accelerations.
|
||||||
|
* These growth accelerators speed up the growth of animals or plants.
|
||||||
|
*/
|
||||||
|
package io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.accelerators;
|
@ -0,0 +1,140 @@
|
|||||||
|
package io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.enchanting;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
|
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.enchantments.Enchantment;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.inventory.meta.EnchantmentStorageMeta;
|
||||||
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
|
import org.bukkit.inventory.meta.Repairable;
|
||||||
|
|
||||||
|
import io.github.thebusybiscuit.cscorelib2.inventory.InvUtils;
|
||||||
|
import io.github.thebusybiscuit.slimefun4.api.events.AutoDisenchantEvent;
|
||||||
|
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.AContainer;
|
||||||
|
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.MachineRecipe;
|
||||||
|
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
||||||
|
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link AutoDisenchanter}, in contrast to the {@link AutoEnchanter}, removes
|
||||||
|
* {@link Enchantment Enchantments} from a given {@link ItemStack} and transfers them
|
||||||
|
* to a book.
|
||||||
|
*
|
||||||
|
* @author TheBusyBiscuit
|
||||||
|
* @author Walshy
|
||||||
|
* @author poma123
|
||||||
|
*
|
||||||
|
* @see AutoEnchanter
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class AutoDisenchanter extends AContainer {
|
||||||
|
|
||||||
|
@ParametersAreNonnullByDefault
|
||||||
|
public AutoDisenchanter(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
||||||
|
super(category, item, recipeType, recipe);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack getProgressBar() {
|
||||||
|
return new ItemStack(Material.DIAMOND_CHESTPLATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected MachineRecipe findNextRecipe(BlockMenu menu) {
|
||||||
|
Map<Enchantment, Integer> enchantments = new HashMap<>();
|
||||||
|
|
||||||
|
for (int slot : getInputSlots()) {
|
||||||
|
ItemStack item = menu.getItemInSlot(slot);
|
||||||
|
|
||||||
|
if (!isDisenchantable(item)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
AutoDisenchantEvent event = new AutoDisenchantEvent(item);
|
||||||
|
Bukkit.getPluginManager().callEvent(event);
|
||||||
|
|
||||||
|
if (event.isCancelled()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemStack target = menu.getItemInSlot(slot == getInputSlots()[0] ? getInputSlots()[1] : getInputSlots()[0]);
|
||||||
|
|
||||||
|
// Disenchanting
|
||||||
|
if (target != null && target.getType() == Material.BOOK) {
|
||||||
|
int amount = 0;
|
||||||
|
|
||||||
|
for (Map.Entry<Enchantment, Integer> entry : item.getEnchantments().entrySet()) {
|
||||||
|
enchantments.put(entry.getKey(), entry.getValue());
|
||||||
|
amount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (amount > 0) {
|
||||||
|
ItemStack disenchantedItem = item.clone();
|
||||||
|
disenchantedItem.setAmount(1);
|
||||||
|
|
||||||
|
ItemStack book = new ItemStack(Material.ENCHANTED_BOOK);
|
||||||
|
transferEnchantments(disenchantedItem, book, enchantments);
|
||||||
|
|
||||||
|
MachineRecipe recipe = new MachineRecipe(90 * amount / this.getSpeed(), new ItemStack[] { target, item }, new ItemStack[] { disenchantedItem, book });
|
||||||
|
|
||||||
|
if (!InvUtils.fitAll(menu.toInventory(), recipe.getOutput(), getOutputSlots())) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int inputSlot : getInputSlots()) {
|
||||||
|
menu.consumeItem(inputSlot);
|
||||||
|
}
|
||||||
|
|
||||||
|
return recipe;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void transferEnchantments(ItemStack item, ItemStack book, Map<Enchantment, Integer> enchantments) {
|
||||||
|
ItemMeta itemMeta = item.getItemMeta();
|
||||||
|
ItemMeta bookMeta = book.getItemMeta();
|
||||||
|
((Repairable) bookMeta).setRepairCost(((Repairable) itemMeta).getRepairCost());
|
||||||
|
((Repairable) itemMeta).setRepairCost(0);
|
||||||
|
item.setItemMeta(itemMeta);
|
||||||
|
book.setItemMeta(bookMeta);
|
||||||
|
|
||||||
|
EnchantmentStorageMeta meta = (EnchantmentStorageMeta) book.getItemMeta();
|
||||||
|
|
||||||
|
for (Map.Entry<Enchantment, Integer> entry : enchantments.entrySet()) {
|
||||||
|
item.removeEnchantment(entry.getKey());
|
||||||
|
meta.addStoredEnchant(entry.getKey(), entry.getValue(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
book.setItemMeta(meta);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isDisenchantable(@Nullable ItemStack item) {
|
||||||
|
if (item == null) {
|
||||||
|
return false;
|
||||||
|
} else if (item.getType() != Material.BOOK) {
|
||||||
|
// ^ This stops endless checks of getByItem for books
|
||||||
|
SlimefunItem sfItem = SlimefunItem.getByItem(item);
|
||||||
|
return sfItem == null || sfItem.isDisenchantable();
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getMachineIdentifier() {
|
||||||
|
return "AUTO_DISENCHANTER";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,102 @@
|
|||||||
|
package io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.enchanting;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
|
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.enchantments.Enchantment;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.inventory.meta.EnchantmentStorageMeta;
|
||||||
|
|
||||||
|
import io.github.thebusybiscuit.cscorelib2.inventory.InvUtils;
|
||||||
|
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.AContainer;
|
||||||
|
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.MachineRecipe;
|
||||||
|
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
||||||
|
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu;
|
||||||
|
|
||||||
|
public class AutoEnchanter extends AContainer {
|
||||||
|
|
||||||
|
@ParametersAreNonnullByDefault
|
||||||
|
public AutoEnchanter(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
||||||
|
super(category, item, recipeType, recipe);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack getProgressBar() {
|
||||||
|
return new ItemStack(Material.GOLDEN_CHESTPLATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected MachineRecipe findNextRecipe(BlockMenu menu) {
|
||||||
|
for (int slot : getInputSlots()) {
|
||||||
|
ItemStack target = menu.getItemInSlot(slot == getInputSlots()[0] ? getInputSlots()[1] : getInputSlots()[0]);
|
||||||
|
|
||||||
|
// Check if the item is enchantable
|
||||||
|
if (!isEnchantable(target)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemStack item = menu.getItemInSlot(slot);
|
||||||
|
|
||||||
|
if (item != null && item.getType() == Material.ENCHANTED_BOOK && target != null) {
|
||||||
|
Map<Enchantment, Integer> enchantments = new HashMap<>();
|
||||||
|
int amount = 0;
|
||||||
|
EnchantmentStorageMeta meta = (EnchantmentStorageMeta) item.getItemMeta();
|
||||||
|
|
||||||
|
for (Map.Entry<Enchantment, Integer> e : meta.getStoredEnchants().entrySet()) {
|
||||||
|
if (e.getKey().canEnchantItem(target)) {
|
||||||
|
amount++;
|
||||||
|
enchantments.put(e.getKey(), e.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (amount > 0) {
|
||||||
|
ItemStack enchantedItem = target.clone();
|
||||||
|
enchantedItem.setAmount(1);
|
||||||
|
|
||||||
|
for (Map.Entry<Enchantment, Integer> entry : enchantments.entrySet()) {
|
||||||
|
enchantedItem.addUnsafeEnchantment(entry.getKey(), entry.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
MachineRecipe recipe = new MachineRecipe(75 * amount / this.getSpeed(), new ItemStack[] { target, item }, new ItemStack[] { enchantedItem, new ItemStack(Material.BOOK) });
|
||||||
|
|
||||||
|
if (!InvUtils.fitAll(menu.toInventory(), recipe.getOutput(), getOutputSlots())) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int inputSlot : getInputSlots()) {
|
||||||
|
menu.consumeItem(inputSlot);
|
||||||
|
}
|
||||||
|
|
||||||
|
return recipe;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isEnchantable(ItemStack item) {
|
||||||
|
SlimefunItem sfItem = null;
|
||||||
|
|
||||||
|
// stops endless checks of getByItem for enchanted book stacks.
|
||||||
|
if (item != null && item.getType() != Material.ENCHANTED_BOOK) {
|
||||||
|
sfItem = SlimefunItem.getByItem(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
return sfItem == null || sfItem.isEnchantable();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getMachineIdentifier() {
|
||||||
|
return "AUTO_ENCHANTER";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines;
|
package io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.enchanting;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -54,6 +54,7 @@ public class BookBinder extends AContainer {
|
|||||||
Map<Enchantment, Integer> storedTargetEnchantments = targetMeta.getStoredEnchants();
|
Map<Enchantment, Integer> storedTargetEnchantments = targetMeta.getStoredEnchants();
|
||||||
Map<Enchantment, Integer> enchantments = combineEnchantments(storedItemEnchantments, storedTargetEnchantments);
|
Map<Enchantment, Integer> enchantments = combineEnchantments(storedItemEnchantments, storedTargetEnchantments);
|
||||||
|
|
||||||
|
// Just return if no enchantments exist. This shouldn't ever happen. :NotLikeThis:
|
||||||
if (enchantments.size() > 0) {
|
if (enchantments.size() > 0) {
|
||||||
ItemStack book = new ItemStack(Material.ENCHANTED_BOOK);
|
ItemStack book = new ItemStack(Material.ENCHANTED_BOOK);
|
||||||
|
|
||||||
@ -63,6 +64,11 @@ public class BookBinder extends AContainer {
|
|||||||
enchantMeta.addStoredEnchant(entry.getKey(), entry.getValue(), bypassVanillaMaxLevel.getValue());
|
enchantMeta.addStoredEnchant(entry.getKey(), entry.getValue(), bypassVanillaMaxLevel.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Make sure we never return an enchanted book with no enchantments.
|
||||||
|
if (enchantMeta.getStoredEnchants().isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
book.setItemMeta(enchantMeta);
|
book.setItemMeta(enchantMeta);
|
||||||
|
|
||||||
MachineRecipe recipe = new MachineRecipe(25 * (enchantments.size() / this.getSpeed()), new ItemStack[] { target, item }, new ItemStack[] { book });
|
MachineRecipe recipe = new MachineRecipe(25 * (enchantments.size() / this.getSpeed()), new ItemStack[] { target, item }, new ItemStack[] { book });
|
||||||
@ -109,15 +115,25 @@ public class BookBinder extends AContainer {
|
|||||||
|
|
||||||
for (Map.Entry<Enchantment, Integer> entry : ech2.entrySet()) {
|
for (Map.Entry<Enchantment, Integer> entry : ech2.entrySet()) {
|
||||||
for (Map.Entry<Enchantment, Integer> conflictsWith : enchantments.entrySet()) {
|
for (Map.Entry<Enchantment, Integer> conflictsWith : enchantments.entrySet()) {
|
||||||
if (entry.getKey().conflictsWith(conflictsWith.getKey())) {
|
|
||||||
|
// Check if entry enchantment and conflictsWith enchantment conflict, and confirm that the enchantsments
|
||||||
|
// aren't the exact same.
|
||||||
|
if (entry.getKey().conflictsWith(conflictsWith.getKey()) && !entry.getKey().equals(conflictsWith.getKey())) {
|
||||||
conflicts = true;
|
conflicts = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!conflicts) {
|
if (!conflicts) {
|
||||||
enchantments.merge(entry.getKey(), entry.getValue(), (a, b) -> {
|
enchantments.merge(entry.getKey(), entry.getValue(), (a, b) -> {
|
||||||
|
int enchantMaxLevel = entry.getKey().getMaxLevel();
|
||||||
|
|
||||||
if (a.intValue() == b.intValue()) {
|
if (a.intValue() == b.intValue()) {
|
||||||
if (hasCustomMaxLevel.getValue()) {
|
|
||||||
|
// Confirm the entry's enchant level doesn't go over the maximum unless it uses
|
||||||
|
// bypass-vanilla-max-level
|
||||||
|
if (enchantMaxLevel <= a && !bypassVanillaMaxLevel.getValue()) {
|
||||||
|
return enchantMaxLevel;
|
||||||
|
} else if (hasCustomMaxLevel.getValue()) {
|
||||||
return a + 1 > customMaxLevel.getValue() ? customMaxLevel.getValue() : a + 1;
|
return a + 1 > customMaxLevel.getValue() ? customMaxLevel.getValue() : a + 1;
|
||||||
} else {
|
} else {
|
||||||
return a + 1;
|
return a + 1;
|
||||||
@ -125,7 +141,11 @@ public class BookBinder extends AContainer {
|
|||||||
} else {
|
} else {
|
||||||
int highestLevel = Math.max(a, b);
|
int highestLevel = Math.max(a, b);
|
||||||
|
|
||||||
if (hasCustomMaxLevel.getValue()) {
|
// Confirm the entry's enchant level doesn't go over the maximum unless it uses
|
||||||
|
// bypass-vanilla-max-level
|
||||||
|
if (enchantMaxLevel <= highestLevel && !bypassVanillaMaxLevel.getValue()) {
|
||||||
|
return enchantMaxLevel;
|
||||||
|
} else if (hasCustomMaxLevel.getValue()) {
|
||||||
return highestLevel > customMaxLevel.getValue() ? customMaxLevel.getValue() : highestLevel;
|
return highestLevel > customMaxLevel.getValue() ? customMaxLevel.getValue() : highestLevel;
|
||||||
} else {
|
} else {
|
||||||
return highestLevel;
|
return highestLevel;
|
@ -0,0 +1,7 @@
|
|||||||
|
/**
|
||||||
|
* This package contains any electric machines related to enchanting.
|
||||||
|
* Prominent examples are the
|
||||||
|
* {@link io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.enchanting.AutoEnchanter} and
|
||||||
|
* {@link io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.enchanting.AutoDisenchanter}
|
||||||
|
*/
|
||||||
|
package io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.enchanting;
|
@ -1,4 +1,4 @@
|
|||||||
package io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines;
|
package io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.entities;
|
||||||
|
|
||||||
import org.bukkit.Effect;
|
import org.bukkit.Effect;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
@ -1,4 +1,4 @@
|
|||||||
package io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines;
|
package io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.entities;
|
||||||
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
|
||||||
@ -25,14 +25,14 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
|||||||
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu;
|
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu;
|
||||||
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset;
|
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset;
|
||||||
|
|
||||||
public class XPCollector extends SlimefunItem implements InventoryBlock, EnergyNetComponent {
|
public class ExpCollector extends SlimefunItem implements InventoryBlock, EnergyNetComponent {
|
||||||
|
|
||||||
private final int[] border = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26 };
|
private final int[] border = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26 };
|
||||||
|
|
||||||
private static final int ENERGY_CONSUMPTION = 10;
|
private static final int ENERGY_CONSUMPTION = 10;
|
||||||
private static final String DATA_KEY = "stored-exp";
|
private static final String DATA_KEY = "stored-exp";
|
||||||
|
|
||||||
public XPCollector(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
public ExpCollector(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
||||||
super(category, item, recipeType, recipe);
|
super(category, item, recipeType, recipe);
|
||||||
|
|
||||||
createPreset(this, this::constructMenu);
|
createPreset(this, this::constructMenu);
|
||||||
@ -91,7 +91,7 @@ public class XPCollector extends SlimefunItem implements InventoryBlock, EnergyN
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void tick(Block b, SlimefunItem sf, Config data) {
|
public void tick(Block b, SlimefunItem sf, Config data) {
|
||||||
XPCollector.this.tick(b);
|
ExpCollector.this.tick(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
@ -1,4 +1,4 @@
|
|||||||
package io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines;
|
package io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.entities;
|
||||||
|
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
@ -1,4 +1,4 @@
|
|||||||
package io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines;
|
package io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.entities;
|
||||||
|
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
@ -0,0 +1,6 @@
|
|||||||
|
/**
|
||||||
|
* This package contains any electric machines related to {@link org.bukkit.entity.Entity} interactions, most notably
|
||||||
|
* the
|
||||||
|
* {@link io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.entities.AbstractEntityAssembler}.
|
||||||
|
*/
|
||||||
|
package io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.entities;
|
@ -24,10 +24,12 @@ import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction;
|
|||||||
import io.github.thebusybiscuit.slimefun4.api.events.ReactorExplodeEvent;
|
import io.github.thebusybiscuit.slimefun4.api.events.ReactorExplodeEvent;
|
||||||
import io.github.thebusybiscuit.slimefun4.core.attributes.HologramOwner;
|
import io.github.thebusybiscuit.slimefun4.core.attributes.HologramOwner;
|
||||||
import io.github.thebusybiscuit.slimefun4.core.attributes.Processor;
|
import io.github.thebusybiscuit.slimefun4.core.attributes.Processor;
|
||||||
|
import io.github.thebusybiscuit.slimefun4.core.handlers.BlockBreakHandler;
|
||||||
import io.github.thebusybiscuit.slimefun4.core.machines.FuelOperation;
|
import io.github.thebusybiscuit.slimefun4.core.machines.FuelOperation;
|
||||||
import io.github.thebusybiscuit.slimefun4.core.machines.MachineProcessor;
|
import io.github.thebusybiscuit.slimefun4.core.machines.MachineProcessor;
|
||||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
|
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
|
||||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||||
|
import io.github.thebusybiscuit.slimefun4.implementation.handlers.SimpleBlockBreakHandler;
|
||||||
import io.github.thebusybiscuit.slimefun4.implementation.items.cargo.ReactorAccessPort;
|
import io.github.thebusybiscuit.slimefun4.implementation.items.cargo.ReactorAccessPort;
|
||||||
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.AbstractEnergyProvider;
|
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.AbstractEnergyProvider;
|
||||||
import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils;
|
import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils;
|
||||||
@ -73,7 +75,6 @@ public abstract class Reactor extends AbstractEnergyProvider implements Hologram
|
|||||||
private static final int[] border_4 = { 25, 34, 43 };
|
private static final int[] border_4 = { 25, 34, 43 };
|
||||||
|
|
||||||
private final Set<Location> explosionsQueue = new HashSet<>();
|
private final Set<Location> explosionsQueue = new HashSet<>();
|
||||||
|
|
||||||
private final MachineProcessor<FuelOperation> processor = new MachineProcessor<>();
|
private final MachineProcessor<FuelOperation> processor = new MachineProcessor<>();
|
||||||
|
|
||||||
@ParametersAreNonnullByDefault
|
@ParametersAreNonnullByDefault
|
||||||
@ -109,7 +110,21 @@ public abstract class Reactor extends AbstractEnergyProvider implements Hologram
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
registerBlockHandler(getId(), (p, b, tool, reason) -> {
|
addItemHandler(onBreak());
|
||||||
|
registerDefaultFuelTypes();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MachineProcessor<FuelOperation> getMachineProcessor() {
|
||||||
|
return processor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
private BlockBreakHandler onBreak() {
|
||||||
|
return new SimpleBlockBreakHandler() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBlockBreak(@Nonnull Block b) {
|
||||||
BlockMenu inv = BlockStorage.getInventory(b);
|
BlockMenu inv = BlockStorage.getInventory(b);
|
||||||
|
|
||||||
if (inv != null) {
|
if (inv != null) {
|
||||||
@ -120,15 +135,8 @@ public abstract class Reactor extends AbstractEnergyProvider implements Hologram
|
|||||||
|
|
||||||
processor.removeOperation(b);
|
processor.removeOperation(b);
|
||||||
removeHologram(b);
|
removeHologram(b);
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
registerDefaultFuelTypes();
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
@Override
|
|
||||||
public MachineProcessor<FuelOperation> getMachineProcessor() {
|
|
||||||
return processor;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void updateInventory(@Nonnull BlockMenu menu, @Nonnull Block b) {
|
protected void updateInventory(@Nonnull BlockMenu menu, @Nonnull Block b) {
|
||||||
|
@ -21,12 +21,15 @@ import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetComponent;
|
|||||||
import io.github.thebusybiscuit.slimefun4.core.attributes.HologramOwner;
|
import io.github.thebusybiscuit.slimefun4.core.attributes.HologramOwner;
|
||||||
import io.github.thebusybiscuit.slimefun4.core.attributes.Processor;
|
import io.github.thebusybiscuit.slimefun4.core.attributes.Processor;
|
||||||
import io.github.thebusybiscuit.slimefun4.core.attributes.RecipeDisplayItem;
|
import io.github.thebusybiscuit.slimefun4.core.attributes.RecipeDisplayItem;
|
||||||
|
import io.github.thebusybiscuit.slimefun4.core.handlers.BlockBreakHandler;
|
||||||
import io.github.thebusybiscuit.slimefun4.core.handlers.BlockPlaceHandler;
|
import io.github.thebusybiscuit.slimefun4.core.handlers.BlockPlaceHandler;
|
||||||
import io.github.thebusybiscuit.slimefun4.core.machines.MachineProcessor;
|
import io.github.thebusybiscuit.slimefun4.core.machines.MachineProcessor;
|
||||||
import io.github.thebusybiscuit.slimefun4.core.machines.MiningOperation;
|
import io.github.thebusybiscuit.slimefun4.core.machines.MiningOperation;
|
||||||
import io.github.thebusybiscuit.slimefun4.core.networks.energy.EnergyNetComponentType;
|
import io.github.thebusybiscuit.slimefun4.core.networks.energy.EnergyNetComponentType;
|
||||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||||
|
import io.github.thebusybiscuit.slimefun4.implementation.handlers.SimpleBlockBreakHandler;
|
||||||
import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config;
|
import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config;
|
||||||
|
// github.com/Slimefun/Slimefun4.git
|
||||||
import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu.AdvancedMenuClickHandler;
|
import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu.AdvancedMenuClickHandler;
|
||||||
import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ClickAction;
|
import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ClickAction;
|
||||||
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
|
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
|
||||||
@ -56,20 +59,10 @@ public class GEOMiner extends SlimefunItem implements RecipeDisplayItem, EnergyN
|
|||||||
|
|
||||||
processor.setProgressBar(new ItemStack(Material.DIAMOND_PICKAXE));
|
processor.setProgressBar(new ItemStack(Material.DIAMOND_PICKAXE));
|
||||||
createPreset(this, getItemName(), this::constructMenu);
|
createPreset(this, getItemName(), this::constructMenu);
|
||||||
addItemHandler(onPlace());
|
addItemHandler(onPlace(), onBreak());
|
||||||
|
|
||||||
registerBlockHandler(getId(), (p, b, stack, reason) -> {
|
// Unregister the Block handler from AContainer (Fixes #2861)
|
||||||
removeHologram(b);
|
registerBlockHandler(getId(), null);
|
||||||
|
|
||||||
BlockMenu inv = BlockStorage.getInventory(b);
|
|
||||||
|
|
||||||
if (inv != null) {
|
|
||||||
inv.dropItems(b.getLocation(), OUTPUT_SLOTS);
|
|
||||||
}
|
|
||||||
|
|
||||||
getMachineProcessor().removeOperation(b);
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -88,6 +81,24 @@ public class GEOMiner extends SlimefunItem implements RecipeDisplayItem, EnergyN
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
private BlockBreakHandler onBreak() {
|
||||||
|
return new SimpleBlockBreakHandler() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBlockBreak(@Nonnull Block b) {
|
||||||
|
removeHologram(b);
|
||||||
|
BlockMenu inv = BlockStorage.getInventory(b);
|
||||||
|
|
||||||
|
if (inv != null) {
|
||||||
|
inv.dropItems(b.getLocation(), OUTPUT_SLOTS);
|
||||||
|
}
|
||||||
|
|
||||||
|
processor.removeOperation(b);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<ItemStack> getDisplayRecipes() {
|
public List<ItemStack> getDisplayRecipes() {
|
||||||
List<ItemStack> displayRecipes = new LinkedList<>();
|
List<ItemStack> displayRecipes = new LinkedList<>();
|
||||||
|
@ -1,12 +1,19 @@
|
|||||||
package io.github.thebusybiscuit.slimefun4.implementation.items.gps;
|
package io.github.thebusybiscuit.slimefun4.implementation.items.gps;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
|
|
||||||
|
import org.bukkit.Location;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
|
import org.bukkit.event.block.BlockBreakEvent;
|
||||||
import org.bukkit.event.block.BlockPlaceEvent;
|
import org.bukkit.event.block.BlockPlaceEvent;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetComponent;
|
import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetComponent;
|
||||||
|
import io.github.thebusybiscuit.slimefun4.core.handlers.BlockBreakHandler;
|
||||||
import io.github.thebusybiscuit.slimefun4.core.handlers.BlockPlaceHandler;
|
import io.github.thebusybiscuit.slimefun4.core.handlers.BlockPlaceHandler;
|
||||||
import io.github.thebusybiscuit.slimefun4.core.networks.energy.EnergyNetComponentType;
|
import io.github.thebusybiscuit.slimefun4.core.networks.energy.EnergyNetComponentType;
|
||||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||||
@ -23,16 +30,12 @@ public abstract class GPSTransmitter extends SimpleSlimefunItem<BlockTicker> imp
|
|||||||
|
|
||||||
private final int capacity;
|
private final int capacity;
|
||||||
|
|
||||||
|
@ParametersAreNonnullByDefault
|
||||||
public GPSTransmitter(Category category, int tier, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
public GPSTransmitter(Category category, int tier, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
||||||
super(category, item, recipeType, recipe);
|
super(category, item, recipeType, recipe);
|
||||||
this.capacity = 4 << (2 * tier);
|
this.capacity = 4 << (2 * tier);
|
||||||
|
|
||||||
addItemHandler(onPlace());
|
addItemHandler(onPlace(), onBreak());
|
||||||
registerBlockHandler(getId(), (p, b, stack, reason) -> {
|
|
||||||
UUID owner = UUID.fromString(BlockStorage.getLocationInfo(b.getLocation(), "owner"));
|
|
||||||
SlimefunPlugin.getGPSNetwork().updateTransmitter(b.getLocation(), owner, false);
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -40,6 +43,7 @@ public abstract class GPSTransmitter extends SimpleSlimefunItem<BlockTicker> imp
|
|||||||
return capacity;
|
return capacity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
private BlockPlaceHandler onPlace() {
|
private BlockPlaceHandler onPlace() {
|
||||||
return new BlockPlaceHandler(false) {
|
return new BlockPlaceHandler(false) {
|
||||||
|
|
||||||
@ -50,6 +54,19 @@ public abstract class GPSTransmitter extends SimpleSlimefunItem<BlockTicker> imp
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
private BlockBreakHandler onBreak() {
|
||||||
|
return new BlockBreakHandler(false, false) {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPlayerBreak(BlockBreakEvent e, ItemStack item, List<ItemStack> drops) {
|
||||||
|
Location l = e.getBlock().getLocation();
|
||||||
|
UUID owner = UUID.fromString(BlockStorage.getLocationInfo(l, "owner"));
|
||||||
|
SlimefunPlugin.getGPSNetwork().updateTransmitter(l, owner, false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
public abstract int getMultiplier(int y);
|
public abstract int getMultiplier(int y);
|
||||||
|
|
||||||
public abstract int getEnergyConsumption();
|
public abstract int getEnergyConsumption();
|
||||||
|
@ -9,6 +9,9 @@ import java.util.Map;
|
|||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.concurrent.ThreadLocalRandom;
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
|
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.Particle;
|
import org.bukkit.Particle;
|
||||||
@ -25,7 +28,6 @@ import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunIte
|
|||||||
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
|
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
|
||||||
import me.mrCookieSlime.Slimefun.Objects.Category;
|
import me.mrCookieSlime.Slimefun.Objects.Category;
|
||||||
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
|
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
|
||||||
import me.mrCookieSlime.Slimefun.api.Slimefun;
|
|
||||||
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -42,6 +44,7 @@ public class EnchantmentRune extends SimpleSlimefunItem<ItemDropHandler> {
|
|||||||
private static final double RANGE = 1.5;
|
private static final double RANGE = 1.5;
|
||||||
private final Map<Material, List<Enchantment>> applicableEnchantments = new EnumMap<>(Material.class);
|
private final Map<Material, List<Enchantment>> applicableEnchantments = new EnumMap<>(Material.class);
|
||||||
|
|
||||||
|
@ParametersAreNonnullByDefault
|
||||||
public EnchantmentRune(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
public EnchantmentRune(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
||||||
super(category, item, recipeType, recipe);
|
super(category, item, recipeType, recipe);
|
||||||
|
|
||||||
@ -49,7 +52,7 @@ public class EnchantmentRune extends SimpleSlimefunItem<ItemDropHandler> {
|
|||||||
List<Enchantment> enchantments = new ArrayList<>();
|
List<Enchantment> enchantments = new ArrayList<>();
|
||||||
|
|
||||||
for (Enchantment enchantment : Enchantment.values()) {
|
for (Enchantment enchantment : Enchantment.values()) {
|
||||||
if (enchantment == Enchantment.BINDING_CURSE || enchantment == Enchantment.VANISHING_CURSE) {
|
if (enchantment.equals(Enchantment.BINDING_CURSE) || enchantment.equals(Enchantment.VANISHING_CURSE)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,7 +69,7 @@ public class EnchantmentRune extends SimpleSlimefunItem<ItemDropHandler> {
|
|||||||
public ItemDropHandler getItemHandler() {
|
public ItemDropHandler getItemHandler() {
|
||||||
return (e, p, item) -> {
|
return (e, p, item) -> {
|
||||||
if (isItem(item.getItemStack())) {
|
if (isItem(item.getItemStack())) {
|
||||||
if (Slimefun.hasUnlocked(p, this, true)) {
|
if (canUse(p, true)) {
|
||||||
SlimefunPlugin.runSync(() -> {
|
SlimefunPlugin.runSync(() -> {
|
||||||
try {
|
try {
|
||||||
addRandomEnchantment(p, item);
|
addRandomEnchantment(p, item);
|
||||||
@ -83,7 +86,7 @@ public class EnchantmentRune extends SimpleSlimefunItem<ItemDropHandler> {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addRandomEnchantment(Player p, Item rune) {
|
private void addRandomEnchantment(@Nonnull Player p, @Nonnull Item rune) {
|
||||||
// Being sure the entity is still valid and not picked up or whatsoever.
|
// Being sure the entity is still valid and not picked up or whatsoever.
|
||||||
if (!rune.isValid()) {
|
if (!rune.isValid()) {
|
||||||
return;
|
return;
|
||||||
@ -106,8 +109,18 @@ public class EnchantmentRune extends SimpleSlimefunItem<ItemDropHandler> {
|
|||||||
potentialEnchantments = new ArrayList<>(potentialEnchantments);
|
potentialEnchantments = new ArrayList<>(potentialEnchantments);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Removing the enchantments that the item already has from enchantmentSet
|
SlimefunItem slimefunItem = SlimefunItem.getByItem(itemStack);
|
||||||
// This also removes any conflicting enchantments
|
|
||||||
|
// Fixes #2878 - Respect enchatability config setting.
|
||||||
|
if (slimefunItem != null && !slimefunItem.isEnchantable()) {
|
||||||
|
SlimefunPlugin.getLocalization().sendMessage(p, "messages.enchantment-rune.fail", true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Removing the enchantments that the item already has from enchantmentSet.
|
||||||
|
* This also removes any conflicting enchantments
|
||||||
|
*/
|
||||||
removeIllegalEnchantments(itemStack, potentialEnchantments);
|
removeIllegalEnchantments(itemStack, potentialEnchantments);
|
||||||
|
|
||||||
if (potentialEnchantments.isEmpty()) {
|
if (potentialEnchantments.isEmpty()) {
|
||||||
@ -144,7 +157,7 @@ public class EnchantmentRune extends SimpleSlimefunItem<ItemDropHandler> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getRandomlevel(Enchantment enchantment) {
|
private int getRandomlevel(@Nonnull Enchantment enchantment) {
|
||||||
int level = 1;
|
int level = 1;
|
||||||
|
|
||||||
if (enchantment.getMaxLevel() != 1) {
|
if (enchantment.getMaxLevel() != 1) {
|
||||||
@ -154,7 +167,7 @@ public class EnchantmentRune extends SimpleSlimefunItem<ItemDropHandler> {
|
|||||||
return level;
|
return level;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void removeIllegalEnchantments(ItemStack target, List<Enchantment> potentialEnchantments) {
|
private void removeIllegalEnchantments(@Nonnull ItemStack target, @Nonnull List<Enchantment> potentialEnchantments) {
|
||||||
for (Enchantment enchantment : target.getEnchantments().keySet()) {
|
for (Enchantment enchantment : target.getEnchantments().keySet()) {
|
||||||
Iterator<Enchantment> iterator = potentialEnchantments.iterator();
|
Iterator<Enchantment> iterator = potentialEnchantments.iterator();
|
||||||
|
|
||||||
@ -169,7 +182,7 @@ public class EnchantmentRune extends SimpleSlimefunItem<ItemDropHandler> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean findCompatibleItem(Entity n) {
|
private boolean findCompatibleItem(@Nonnull Entity n) {
|
||||||
if (n instanceof Item) {
|
if (n instanceof Item) {
|
||||||
Item item = (Item) n;
|
Item item = (Item) n;
|
||||||
|
|
||||||
|
@ -3,6 +3,8 @@ package io.github.thebusybiscuit.slimefun4.implementation.items.magical.runes;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Sound;
|
import org.bukkit.Sound;
|
||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.entity.Entity;
|
||||||
@ -19,7 +21,6 @@ import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
|
|||||||
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
|
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
|
||||||
import me.mrCookieSlime.Slimefun.Objects.Category;
|
import me.mrCookieSlime.Slimefun.Objects.Category;
|
||||||
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
|
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
|
||||||
import me.mrCookieSlime.Slimefun.api.Slimefun;
|
|
||||||
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -47,7 +48,7 @@ public class SoulboundRune extends SimpleSlimefunItem<ItemDropHandler> {
|
|||||||
return (e, p, item) -> {
|
return (e, p, item) -> {
|
||||||
if (isItem(item.getItemStack())) {
|
if (isItem(item.getItemStack())) {
|
||||||
|
|
||||||
if (!Slimefun.hasUnlocked(p, this, true)) {
|
if (!canUse(p, true)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,7 +60,7 @@ public class SoulboundRune extends SimpleSlimefunItem<ItemDropHandler> {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private void activate(Player p, Item rune) {
|
private void activate(@Nonnull Player p, @Nonnull Item rune) {
|
||||||
// Being sure the entity is still valid and not picked up or whatsoever.
|
// Being sure the entity is still valid and not picked up or whatsoever.
|
||||||
if (!rune.isValid()) {
|
if (!rune.isValid()) {
|
||||||
return;
|
return;
|
||||||
|
@ -1,5 +1,18 @@
|
|||||||
package io.github.thebusybiscuit.slimefun4.implementation.items.magical.talismans;
|
package io.github.thebusybiscuit.slimefun4.implementation.items.magical.talismans;
|
||||||
|
|
||||||
|
import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting;
|
||||||
|
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||||
|
import io.github.thebusybiscuit.slimefun4.implementation.settings.TalismanEnchantment;
|
||||||
|
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
||||||
|
import org.apache.commons.lang.Validate;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.enchantments.Enchantment;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@ -7,20 +20,6 @@ import java.util.concurrent.ThreadLocalRandom;
|
|||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
import javax.annotation.ParametersAreNonnullByDefault;
|
|
||||||
|
|
||||||
import org.apache.commons.lang.Validate;
|
|
||||||
import org.bukkit.enchantments.Enchantment;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
|
|
||||||
import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting;
|
|
||||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
|
||||||
import io.github.thebusybiscuit.slimefun4.implementation.settings.TalismanEnchantment;
|
|
||||||
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@link MagicianTalisman} is a special kind of {@link Talisman} which awards a {@link Player}
|
* The {@link MagicianTalisman} is a special kind of {@link Talisman} which awards a {@link Player}
|
||||||
* with an extra {@link Enchantment} when they enchant their {@link ItemStack}.
|
* with an extra {@link Enchantment} when they enchant their {@link ItemStack}.
|
||||||
@ -30,12 +29,16 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
|||||||
*/
|
*/
|
||||||
public class MagicianTalisman extends Talisman {
|
public class MagicianTalisman extends Talisman {
|
||||||
|
|
||||||
|
private final ItemSetting<Boolean> allowEnchantmentBooks = new ItemSetting<>("allow-enchantment-books", false);
|
||||||
|
|
||||||
private final Set<TalismanEnchantment> enchantments = new HashSet<>();
|
private final Set<TalismanEnchantment> enchantments = new HashSet<>();
|
||||||
|
|
||||||
@ParametersAreNonnullByDefault
|
@ParametersAreNonnullByDefault
|
||||||
public MagicianTalisman(SlimefunItemStack item, ItemStack[] recipe) {
|
public MagicianTalisman(SlimefunItemStack item, ItemStack[] recipe) {
|
||||||
super(item, recipe, false, false, "magician", 80);
|
super(item, recipe, false, false, "magician", 80);
|
||||||
|
|
||||||
|
addItemSetting(allowEnchantmentBooks);
|
||||||
|
|
||||||
for (Enchantment enchantment : Enchantment.values()) {
|
for (Enchantment enchantment : Enchantment.values()) {
|
||||||
try {
|
try {
|
||||||
for (int i = 1; i <= enchantment.getMaxLevel(); i++) {
|
for (int i = 1; i <= enchantment.getMaxLevel(); i++) {
|
||||||
@ -70,7 +73,7 @@ public class MagicianTalisman extends Talisman {
|
|||||||
|
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
List<TalismanEnchantment> enabled = enchantments.stream()
|
List<TalismanEnchantment> enabled = enchantments.stream()
|
||||||
.filter(e -> e.getEnchantment().canEnchantItem(item))
|
.filter(e -> (isEnchantmentBookAllowed() && item.getType() == Material.BOOK) || e.getEnchantment().canEnchantItem(item))
|
||||||
.filter(e -> hasConflicts(existingEnchantments, e))
|
.filter(e -> hasConflicts(existingEnchantments, e))
|
||||||
.filter(TalismanEnchantment::getValue)
|
.filter(TalismanEnchantment::getValue)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
@ -90,4 +93,13 @@ public class MagicianTalisman extends Talisman {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method checks whether enchantment books
|
||||||
|
* can be given an extra {@link Enchantment} or not.
|
||||||
|
*
|
||||||
|
* @return Whether enchantment books can receive an extra {@link Enchantment}
|
||||||
|
*/
|
||||||
|
public boolean isEnchantmentBookAllowed() {
|
||||||
|
return allowEnchantmentBooks.getValue();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ import javax.annotation.Nonnull;
|
|||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import javax.annotation.ParametersAreNonnullByDefault;
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
|
|
||||||
|
import org.apache.commons.lang.Validate;
|
||||||
import org.bukkit.ChatColor;
|
import org.bukkit.ChatColor;
|
||||||
import org.bukkit.NamespacedKey;
|
import org.bukkit.NamespacedKey;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
@ -33,7 +34,6 @@ import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
|
|||||||
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
|
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
|
||||||
import me.mrCookieSlime.Slimefun.Objects.Category;
|
import me.mrCookieSlime.Slimefun.Objects.Category;
|
||||||
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
|
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
|
||||||
import me.mrCookieSlime.Slimefun.api.Slimefun;
|
|
||||||
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
||||||
|
|
||||||
public class Talisman extends SlimefunItem {
|
public class Talisman extends SlimefunItem {
|
||||||
@ -113,10 +113,6 @@ public class Talisman extends SlimefunItem {
|
|||||||
return effects;
|
return effects;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String getMessageSuffix() {
|
|
||||||
return suffix;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected boolean isEventCancelled() {
|
protected boolean isEventCancelled() {
|
||||||
return cancel;
|
return cancel;
|
||||||
}
|
}
|
||||||
@ -147,36 +143,44 @@ public class Talisman extends SlimefunItem {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean hasMessage(@Nonnull Talisman talisman) {
|
@ParametersAreNonnullByDefault
|
||||||
return talisman.getMessageSuffix() != null;
|
public static boolean trigger(Event e, SlimefunItemStack stack) {
|
||||||
|
return trigger(e, stack.getItem(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ParametersAreNonnullByDefault
|
@ParametersAreNonnullByDefault
|
||||||
public static boolean checkFor(Event e, SlimefunItemStack stack) {
|
public static boolean trigger(Event e, SlimefunItemStack stack, boolean sendMessage) {
|
||||||
return checkFor(e, stack.getItem());
|
return trigger(e, stack.getItem(), sendMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ParametersAreNonnullByDefault
|
@ParametersAreNonnullByDefault
|
||||||
public static boolean checkFor(Event e, SlimefunItem item) {
|
public static boolean trigger(Event e, SlimefunItem item) {
|
||||||
|
return trigger(e, item, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParametersAreNonnullByDefault
|
||||||
|
public static boolean trigger(Event e, SlimefunItem item, boolean sendMessage) {
|
||||||
if (!(item instanceof Talisman)) {
|
if (!(item instanceof Talisman)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Talisman talisman = (Talisman) item;
|
Talisman talisman = (Talisman) item;
|
||||||
|
|
||||||
if (ThreadLocalRandom.current().nextInt(100) > talisman.getChance()) {
|
if (ThreadLocalRandom.current().nextInt(100) > talisman.getChance()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Player p = getPlayerByEventType(e);
|
Player p = getPlayerByEventType(e);
|
||||||
if (p == null || !pass(p, talisman)) {
|
|
||||||
|
if (p == null || !talisman.canEffectsBeApplied(p)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemStack talismanItem = talisman.getItem();
|
ItemStack talismanItem = talisman.getItem();
|
||||||
|
|
||||||
if (SlimefunUtils.containsSimilarItem(p.getInventory(), talismanItem, true)) {
|
if (SlimefunUtils.containsSimilarItem(p.getInventory(), talismanItem, true)) {
|
||||||
if (Slimefun.hasUnlocked(p, talisman, true)) {
|
if (talisman.canUse(p, true)) {
|
||||||
activateTalisman(e, p, p.getInventory(), talisman, talismanItem);
|
activateTalisman(e, p, p.getInventory(), talisman, talismanItem, sendMessage);
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
@ -185,8 +189,8 @@ public class Talisman extends SlimefunItem {
|
|||||||
ItemStack enderTalisman = talisman.getEnderVariant();
|
ItemStack enderTalisman = talisman.getEnderVariant();
|
||||||
|
|
||||||
if (SlimefunUtils.containsSimilarItem(p.getEnderChest(), enderTalisman, true)) {
|
if (SlimefunUtils.containsSimilarItem(p.getEnderChest(), enderTalisman, true)) {
|
||||||
if (Slimefun.hasUnlocked(p, talisman, true)) {
|
if (talisman.canUse(p, true)) {
|
||||||
activateTalisman(e, p, p.getEnderChest(), talisman, enderTalisman);
|
activateTalisman(e, p, p.getEnderChest(), talisman, enderTalisman, sendMessage);
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
@ -198,11 +202,30 @@ public class Talisman extends SlimefunItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@ParametersAreNonnullByDefault
|
@ParametersAreNonnullByDefault
|
||||||
private static void activateTalisman(Event e, Player p, Inventory inv, Talisman talisman, ItemStack talismanItem) {
|
private static void activateTalisman(Event e, Player p, Inventory inv, Talisman talisman, ItemStack talismanItem, boolean sendMessage) {
|
||||||
consumeItem(inv, talisman, talismanItem);
|
consumeItem(inv, talisman, talismanItem);
|
||||||
applyTalismanEffects(p, talisman);
|
applyTalismanEffects(p, talisman);
|
||||||
cancelEvent(e, talisman);
|
cancelEvent(e, talisman);
|
||||||
sendMessage(p, talisman);
|
|
||||||
|
if (sendMessage) {
|
||||||
|
talisman.sendMessage(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParametersAreNonnullByDefault
|
||||||
|
private static void consumeItem(Inventory inv, Talisman talisman, ItemStack talismanItem) {
|
||||||
|
if (talisman.isConsumable()) {
|
||||||
|
ItemStack[] contents = inv.getContents();
|
||||||
|
|
||||||
|
for (int i = 0; i < contents.length; i++) {
|
||||||
|
ItemStack item = contents[i];
|
||||||
|
|
||||||
|
if (SlimefunUtils.isItemSimilar(item, talismanItem, true, false)) {
|
||||||
|
ItemUtils.consumeItem(item, false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ParametersAreNonnullByDefault
|
@ParametersAreNonnullByDefault
|
||||||
@ -219,29 +242,63 @@ public class Talisman extends SlimefunItem {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ParametersAreNonnullByDefault
|
/**
|
||||||
private static void sendMessage(Player p, Talisman talisman) {
|
* This returns whether the {@link Talisman} is silent.
|
||||||
if (hasMessage(talisman)) {
|
* A silent {@link Talisman} will not send a message to a {@link Player}
|
||||||
SlimefunPlugin.getLocalization().sendMessage(p, "messages.talisman." + talisman.getMessageSuffix(), true);
|
* when activated.
|
||||||
}
|
*
|
||||||
|
* @return Whether this {@link Talisman} is silent
|
||||||
|
*/
|
||||||
|
public boolean isSilent() {
|
||||||
|
return getMessageSuffix() == null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ParametersAreNonnullByDefault
|
@Nullable
|
||||||
private static void consumeItem(Inventory inv, Talisman talisman, ItemStack talismanItem) {
|
protected final String getMessageSuffix() {
|
||||||
if (talisman.isConsumable()) {
|
return suffix;
|
||||||
ItemStack[] contents = inv.getContents();
|
|
||||||
for (int i = 0; i < contents.length; i++) {
|
|
||||||
ItemStack item = contents[i];
|
|
||||||
|
|
||||||
if (SlimefunUtils.isItemSimilar(item, talismanItem, true, false)) {
|
|
||||||
ItemUtils.consumeItem(item, false);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method sends the given {@link Player} the message of this {@link Talisman}.
|
||||||
|
* Dependent on the selected config setting, the message will be sent via the actionbar
|
||||||
|
* or in the chat window.
|
||||||
|
*
|
||||||
|
* @param p
|
||||||
|
* The {@link Player} who shall receive the message
|
||||||
|
*/
|
||||||
|
public void sendMessage(@Nonnull Player p) {
|
||||||
|
Validate.notNull(p, "The Player must not be null.");
|
||||||
|
|
||||||
|
// Check if this Talisman has a message
|
||||||
|
if (!isSilent()) {
|
||||||
|
try {
|
||||||
|
String messageKey = "messages.talisman." + getMessageSuffix();
|
||||||
|
|
||||||
|
if (SlimefunPlugin.getRegistry().useActionbarForTalismans()) {
|
||||||
|
// Use the actionbar
|
||||||
|
SlimefunPlugin.getLocalization().sendActionbarMessage(p, messageKey, false);
|
||||||
|
} else {
|
||||||
|
// Send the message via chat
|
||||||
|
SlimefunPlugin.getLocalization().sendMessage(p, messageKey, true);
|
||||||
|
}
|
||||||
|
} catch (Exception x) {
|
||||||
|
error("An Exception was thrown while trying to send a Talisman message", x);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Player getPlayerByEventType(Event e) {
|
private boolean canEffectsBeApplied(@Nonnull Player p) {
|
||||||
|
for (PotionEffect effect : getEffects()) {
|
||||||
|
if (effect != null && p.hasPotionEffect(effect.getType())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private static Player getPlayerByEventType(@Nonnull Event e) {
|
||||||
if (e instanceof EntityDeathEvent) {
|
if (e instanceof EntityDeathEvent) {
|
||||||
return ((EntityDeathEvent) e).getEntity().getKiller();
|
return ((EntityDeathEvent) e).getEntity().getKiller();
|
||||||
} else if (e instanceof BlockBreakEvent) {
|
} else if (e instanceof BlockBreakEvent) {
|
||||||
@ -259,14 +316,4 @@ public class Talisman extends SlimefunItem {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean pass(Player p, SlimefunItem talisman) {
|
|
||||||
for (PotionEffect effect : ((Talisman) talisman).getEffects()) {
|
|
||||||
if (effect != null && p.hasPotionEffect(effect.getType())) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
@ -4,9 +4,9 @@ import javax.annotation.ParametersAreNonnullByDefault;
|
|||||||
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.CropGrowthAccelerator;
|
|
||||||
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.FoodComposter;
|
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.FoodComposter;
|
||||||
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.TreeGrowthAccelerator;
|
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.accelerators.CropGrowthAccelerator;
|
||||||
|
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.accelerators.TreeGrowthAccelerator;
|
||||||
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
|
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
|
||||||
import me.mrCookieSlime.Slimefun.Objects.Category;
|
import me.mrCookieSlime.Slimefun.Objects.Category;
|
||||||
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
|
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
|
||||||
|
@ -6,8 +6,8 @@ import org.bukkit.Material;
|
|||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
|
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
|
||||||
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.AnimalGrowthAccelerator;
|
|
||||||
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.FoodFabricator;
|
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.FoodFabricator;
|
||||||
|
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.accelerators.AnimalGrowthAccelerator;
|
||||||
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
|
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
|
||||||
import me.mrCookieSlime.Slimefun.Objects.Category;
|
import me.mrCookieSlime.Slimefun.Objects.Category;
|
||||||
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
|
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
|
||||||
|
@ -19,7 +19,6 @@ import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
|
|||||||
import io.papermc.lib.PaperLib;
|
import io.papermc.lib.PaperLib;
|
||||||
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
|
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
|
||||||
import me.mrCookieSlime.Slimefun.Objects.Category;
|
import me.mrCookieSlime.Slimefun.Objects.Category;
|
||||||
import me.mrCookieSlime.Slimefun.api.Slimefun;
|
|
||||||
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -48,7 +47,7 @@ abstract class AbstractSmeltery extends MultiBlockMachine {
|
|||||||
if (canCraft(inv, inputs, i)) {
|
if (canCraft(inv, inputs, i)) {
|
||||||
ItemStack output = RecipeType.getRecipeOutputList(this, inputs.get(i)).clone();
|
ItemStack output = RecipeType.getRecipeOutputList(this, inputs.get(i)).clone();
|
||||||
|
|
||||||
if (Slimefun.hasUnlocked(p, output, true)) {
|
if (SlimefunUtils.canPlayerUseItem(p, output, true)) {
|
||||||
Inventory outputInv = findOutputInventory(output, dispBlock, inv);
|
Inventory outputInv = findOutputInventory(output, dispBlock, inv);
|
||||||
|
|
||||||
if (outputInv != null) {
|
if (outputInv != null) {
|
||||||
|
@ -21,7 +21,6 @@ import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
|
|||||||
import io.papermc.lib.PaperLib;
|
import io.papermc.lib.PaperLib;
|
||||||
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
|
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
|
||||||
import me.mrCookieSlime.Slimefun.Objects.Category;
|
import me.mrCookieSlime.Slimefun.Objects.Category;
|
||||||
import me.mrCookieSlime.Slimefun.api.Slimefun;
|
|
||||||
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
||||||
|
|
||||||
public class ArmorForge extends AbstractCraftingTable {
|
public class ArmorForge extends AbstractCraftingTable {
|
||||||
@ -44,7 +43,7 @@ public class ArmorForge extends AbstractCraftingTable {
|
|||||||
if (isCraftable(inv, inputs.get(i))) {
|
if (isCraftable(inv, inputs.get(i))) {
|
||||||
ItemStack output = RecipeType.getRecipeOutputList(this, inputs.get(i)).clone();
|
ItemStack output = RecipeType.getRecipeOutputList(this, inputs.get(i)).clone();
|
||||||
|
|
||||||
if (Slimefun.hasUnlocked(p, output, true)) {
|
if (SlimefunUtils.canPlayerUseItem(p, output, true)) {
|
||||||
craft(p, output, inv, dispenser);
|
craft(p, output, inv, dispenser);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,7 +20,6 @@ import io.papermc.lib.PaperLib;
|
|||||||
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
|
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
|
||||||
import me.mrCookieSlime.Slimefun.Objects.Category;
|
import me.mrCookieSlime.Slimefun.Objects.Category;
|
||||||
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
|
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
|
||||||
import me.mrCookieSlime.Slimefun.api.Slimefun;
|
|
||||||
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
||||||
|
|
||||||
public class EnhancedCraftingTable extends AbstractCraftingTable {
|
public class EnhancedCraftingTable extends AbstractCraftingTable {
|
||||||
@ -43,7 +42,7 @@ public class EnhancedCraftingTable extends AbstractCraftingTable {
|
|||||||
if (isCraftable(inv, inputs.get(i))) {
|
if (isCraftable(inv, inputs.get(i))) {
|
||||||
ItemStack output = RecipeType.getRecipeOutputList(this, inputs.get(i)).clone();
|
ItemStack output = RecipeType.getRecipeOutputList(this, inputs.get(i)).clone();
|
||||||
|
|
||||||
if (Slimefun.hasUnlocked(p, output, true)) {
|
if (SlimefunUtils.canPlayerUseItem(p, output, true)) {
|
||||||
craft(inv, dispenser, p, b, output);
|
craft(inv, dispenser, p, b, output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ import java.util.List;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
|
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.Sound;
|
import org.bukkit.Sound;
|
||||||
@ -27,6 +28,7 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
|||||||
|
|
||||||
public class GrindStone extends MultiBlockMachine {
|
public class GrindStone extends MultiBlockMachine {
|
||||||
|
|
||||||
|
@ParametersAreNonnullByDefault
|
||||||
public GrindStone(Category category, SlimefunItemStack item) {
|
public GrindStone(Category category, SlimefunItemStack item) {
|
||||||
super(category, item, new ItemStack[] { null, null, null, null, new ItemStack(Material.OAK_FENCE), null, null, new CustomItem(Material.DISPENSER, "Dispenser (Facing up)"), null }, BlockFace.SELF);
|
super(category, item, new ItemStack[] { null, null, null, null, new ItemStack(Material.OAK_FENCE), null, null, new CustomItem(Material.DISPENSER, "Dispenser (Facing up)"), null }, BlockFace.SELF);
|
||||||
}
|
}
|
||||||
@ -71,6 +73,9 @@ public class GrindStone extends MultiBlockMachine {
|
|||||||
|
|
||||||
recipes.add(new ItemStack(Material.PRISMARINE));
|
recipes.add(new ItemStack(Material.PRISMARINE));
|
||||||
recipes.add(new ItemStack(Material.PRISMARINE_SHARD, 4));
|
recipes.add(new ItemStack(Material.PRISMARINE_SHARD, 4));
|
||||||
|
|
||||||
|
recipes.add(new ItemStack(Material.NETHER_WART_BLOCK));
|
||||||
|
recipes.add(new ItemStack(Material.NETHER_WART, 9));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -21,7 +21,6 @@ import io.papermc.lib.PaperLib;
|
|||||||
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
|
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
|
||||||
import me.mrCookieSlime.Slimefun.Objects.Category;
|
import me.mrCookieSlime.Slimefun.Objects.Category;
|
||||||
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
|
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
|
||||||
import me.mrCookieSlime.Slimefun.api.Slimefun;
|
|
||||||
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
||||||
|
|
||||||
public class MagicWorkbench extends AbstractCraftingTable {
|
public class MagicWorkbench extends AbstractCraftingTable {
|
||||||
@ -50,7 +49,7 @@ public class MagicWorkbench extends AbstractCraftingTable {
|
|||||||
if (isCraftable(inv, inputs.get(i))) {
|
if (isCraftable(inv, inputs.get(i))) {
|
||||||
ItemStack output = RecipeType.getRecipeOutputList(this, inputs.get(i)).clone();
|
ItemStack output = RecipeType.getRecipeOutputList(this, inputs.get(i)).clone();
|
||||||
|
|
||||||
if (Slimefun.hasUnlocked(p, output, true)) {
|
if (SlimefunUtils.canPlayerUseItem(p, output, true)) {
|
||||||
craft(inv, dispenser, p, b, output);
|
craft(inv, dispenser, p, b, output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,8 @@ package io.github.thebusybiscuit.slimefun4.implementation.items.multiblocks;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
|
|
||||||
import org.bukkit.Effect;
|
import org.bukkit.Effect;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
@ -17,6 +19,7 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
|||||||
|
|
||||||
public class MakeshiftSmeltery extends AbstractSmeltery {
|
public class MakeshiftSmeltery extends AbstractSmeltery {
|
||||||
|
|
||||||
|
@ParametersAreNonnullByDefault
|
||||||
public MakeshiftSmeltery(Category category, SlimefunItemStack item) {
|
public MakeshiftSmeltery(Category category, SlimefunItemStack item) {
|
||||||
super(category, item, new ItemStack[] { null, new ItemStack(Material.OAK_FENCE), null, new ItemStack(Material.BRICKS), new CustomItem(Material.DISPENSER, "Dispenser (Facing up)"), new ItemStack(Material.BRICKS), null, new ItemStack(Material.FLINT_AND_STEEL), null }, BlockFace.DOWN);
|
super(category, item, new ItemStack[] { null, new ItemStack(Material.OAK_FENCE), null, new ItemStack(Material.BRICKS), new CustomItem(Material.DISPENSER, "Dispenser (Facing up)"), new ItemStack(Material.BRICKS), null, new ItemStack(Material.FLINT_AND_STEEL), null }, BlockFace.DOWN);
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,6 @@ import io.papermc.lib.PaperLib;
|
|||||||
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
|
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
|
||||||
import me.mrCookieSlime.Slimefun.Objects.Category;
|
import me.mrCookieSlime.Slimefun.Objects.Category;
|
||||||
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
|
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
|
||||||
import me.mrCookieSlime.Slimefun.api.Slimefun;
|
|
||||||
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -135,7 +134,7 @@ public class OreCrusher extends MultiBlockMachine {
|
|||||||
ItemStack adding = RecipeType.getRecipeOutput(this, convert);
|
ItemStack adding = RecipeType.getRecipeOutput(this, convert);
|
||||||
Inventory outputInv = findOutputInventory(adding, dispBlock, inv);
|
Inventory outputInv = findOutputInventory(adding, dispBlock, inv);
|
||||||
|
|
||||||
if (Slimefun.hasUnlocked(p, adding, true)) {
|
if (SlimefunUtils.canPlayerUseItem(p, adding, true)) {
|
||||||
if (outputInv != null) {
|
if (outputInv != null) {
|
||||||
ItemStack removing = current.clone();
|
ItemStack removing = current.clone();
|
||||||
removing.setAmount(convert.getAmount());
|
removing.setAmount(convert.getAmount());
|
||||||
|
@ -7,6 +7,8 @@ import java.util.Objects;
|
|||||||
import java.util.concurrent.ThreadLocalRandom;
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
|
|
||||||
import org.bukkit.Effect;
|
import org.bukkit.Effect;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
@ -26,6 +28,7 @@ import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting;
|
|||||||
import io.github.thebusybiscuit.slimefun4.api.items.settings.IntRangeSetting;
|
import io.github.thebusybiscuit.slimefun4.api.items.settings.IntRangeSetting;
|
||||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
|
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
|
||||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||||
|
import io.github.thebusybiscuit.slimefun4.implementation.items.blocks.IgnitionChamber;
|
||||||
import io.papermc.lib.PaperLib;
|
import io.papermc.lib.PaperLib;
|
||||||
import me.mrCookieSlime.Slimefun.Objects.Category;
|
import me.mrCookieSlime.Slimefun.Objects.Category;
|
||||||
import me.mrCookieSlime.Slimefun.api.BlockStorage;
|
import me.mrCookieSlime.Slimefun.api.BlockStorage;
|
||||||
@ -36,6 +39,7 @@ public class Smeltery extends AbstractSmeltery {
|
|||||||
private final BlockFace[] faces = { BlockFace.NORTH, BlockFace.EAST, BlockFace.SOUTH, BlockFace.WEST };
|
private final BlockFace[] faces = { BlockFace.NORTH, BlockFace.EAST, BlockFace.SOUTH, BlockFace.WEST };
|
||||||
private final ItemSetting<Integer> fireBreakingChance = new IntRangeSetting("fire-breaking-chance", 0, 34, 100);
|
private final ItemSetting<Integer> fireBreakingChance = new IntRangeSetting("fire-breaking-chance", 0, 34, 100);
|
||||||
|
|
||||||
|
@ParametersAreNonnullByDefault
|
||||||
public Smeltery(Category category, SlimefunItemStack item) {
|
public Smeltery(Category category, SlimefunItemStack item) {
|
||||||
super(category, item, new ItemStack[] { null, new ItemStack(Material.NETHER_BRICK_FENCE), null, new ItemStack(Material.NETHER_BRICKS), new CustomItem(Material.DISPENSER, "Dispenser (Facing up)"), new ItemStack(Material.NETHER_BRICKS), null, new ItemStack(Material.FLINT_AND_STEEL), null }, BlockFace.DOWN);
|
super(category, item, new ItemStack[] { null, new ItemStack(Material.NETHER_BRICK_FENCE), null, new ItemStack(Material.NETHER_BRICKS), new CustomItem(Material.DISPENSER, "Dispenser (Facing up)"), new ItemStack(Material.NETHER_BRICKS), null, new ItemStack(Material.FLINT_AND_STEEL), null }, BlockFace.DOWN);
|
||||||
|
|
||||||
@ -73,6 +77,7 @@ public class Smeltery extends AbstractSmeltery {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ParametersAreNonnullByDefault
|
||||||
private void consumeFire(Player p, Block dispenser, Block b) {
|
private void consumeFire(Player p, Block dispenser, Block b) {
|
||||||
Inventory chamber = findIgnitionChamber(dispenser);
|
Inventory chamber = findIgnitionChamber(dispenser);
|
||||||
|
|
||||||
@ -103,9 +108,12 @@ public class Smeltery extends AbstractSmeltery {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
private Inventory findIgnitionChamber(@Nonnull Block b) {
|
private Inventory findIgnitionChamber(@Nonnull Block b) {
|
||||||
for (BlockFace face : faces) {
|
for (BlockFace face : faces) {
|
||||||
if (b.getRelative(face).getType() == Material.DROPPER && BlockStorage.check(b.getRelative(face), "IGNITION_CHAMBER")) {
|
Block block = b.getRelative(face);
|
||||||
|
|
||||||
|
if (block.getType() == Material.DROPPER && BlockStorage.check(block) instanceof IgnitionChamber) {
|
||||||
BlockState state = PaperLib.getBlockState(b.getRelative(face), false).getState();
|
BlockState state = PaperLib.getBlockState(b.getRelative(face), false).getState();
|
||||||
|
|
||||||
if (state instanceof Dropper) {
|
if (state instanceof Dropper) {
|
||||||
|
@ -3,6 +3,7 @@ package io.github.thebusybiscuit.slimefun4.implementation.items.tools;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.ParametersAreNonnullByDefault;
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
@ -15,6 +16,7 @@ import org.bukkit.event.block.BlockExplodeEvent;
|
|||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction;
|
import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction;
|
||||||
|
import io.github.thebusybiscuit.slimefun4.api.events.ExplosiveToolBreakBlocksEvent;
|
||||||
import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting;
|
import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting;
|
||||||
import io.github.thebusybiscuit.slimefun4.core.attributes.DamageableItem;
|
import io.github.thebusybiscuit.slimefun4.core.attributes.DamageableItem;
|
||||||
import io.github.thebusybiscuit.slimefun4.core.attributes.NotPlaceable;
|
import io.github.thebusybiscuit.slimefun4.core.attributes.NotPlaceable;
|
||||||
@ -39,7 +41,7 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
|||||||
* @see ExplosiveShovel
|
* @see ExplosiveShovel
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class ExplosiveTool extends SimpleSlimefunItem<ToolUseHandler> implements NotPlaceable, DamageableItem {
|
public class ExplosiveTool extends SimpleSlimefunItem<ToolUseHandler> implements NotPlaceable, DamageableItem {
|
||||||
|
|
||||||
private final ItemSetting<Boolean> damageOnUse = new ItemSetting<>("damage-on-use", true);
|
private final ItemSetting<Boolean> damageOnUse = new ItemSetting<>("damage-on-use", true);
|
||||||
private final ItemSetting<Boolean> callExplosionEvent = new ItemSetting<>("call-explosion-event", false);
|
private final ItemSetting<Boolean> callExplosionEvent = new ItemSetting<>("call-explosion-event", false);
|
||||||
@ -51,6 +53,7 @@ class ExplosiveTool extends SimpleSlimefunItem<ToolUseHandler> implements NotPla
|
|||||||
addItemSetting(damageOnUse, callExplosionEvent);
|
addItemSetting(damageOnUse, callExplosionEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public ToolUseHandler getItemHandler() {
|
public ToolUseHandler getItemHandler() {
|
||||||
return (e, tool, fortune, drops) -> {
|
return (e, tool, fortune, drops) -> {
|
||||||
@ -67,6 +70,8 @@ class ExplosiveTool extends SimpleSlimefunItem<ToolUseHandler> implements NotPla
|
|||||||
|
|
||||||
@ParametersAreNonnullByDefault
|
@ParametersAreNonnullByDefault
|
||||||
private void breakBlocks(Player p, ItemStack item, Block b, List<Block> blocks, List<ItemStack> drops) {
|
private void breakBlocks(Player p, ItemStack item, Block b, List<Block> blocks, List<ItemStack> drops) {
|
||||||
|
List<Block> blocksToDestroy = new ArrayList<>();
|
||||||
|
|
||||||
if (callExplosionEvent.getValue().booleanValue()) {
|
if (callExplosionEvent.getValue().booleanValue()) {
|
||||||
BlockExplodeEvent blockExplodeEvent = new BlockExplodeEvent(b, blocks, 0);
|
BlockExplodeEvent blockExplodeEvent = new BlockExplodeEvent(b, blocks, 0);
|
||||||
Bukkit.getServer().getPluginManager().callEvent(blockExplodeEvent);
|
Bukkit.getServer().getPluginManager().callEvent(blockExplodeEvent);
|
||||||
@ -74,17 +79,26 @@ class ExplosiveTool extends SimpleSlimefunItem<ToolUseHandler> implements NotPla
|
|||||||
if (!blockExplodeEvent.isCancelled()) {
|
if (!blockExplodeEvent.isCancelled()) {
|
||||||
for (Block block : blockExplodeEvent.blockList()) {
|
for (Block block : blockExplodeEvent.blockList()) {
|
||||||
if (canBreak(p, block)) {
|
if (canBreak(p, block)) {
|
||||||
breakBlock(p, item, block, drops);
|
blocksToDestroy.add(block);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (Block block : blocks) {
|
for (Block block : blocks) {
|
||||||
if (canBreak(p, block)) {
|
if (canBreak(p, block)) {
|
||||||
breakBlock(p, item, block, drops);
|
blocksToDestroy.add(block);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ExplosiveToolBreakBlocksEvent event = new ExplosiveToolBreakBlocksEvent(p, blocksToDestroy, item, this);
|
||||||
|
Bukkit.getServer().getPluginManager().callEvent(event);
|
||||||
|
|
||||||
|
if (!event.isCancelled()) {
|
||||||
|
for (Block block : blocksToDestroy) {
|
||||||
|
breakBlock(p, item, block, drops);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Block> findBlocks(Block b) {
|
private List<Block> findBlocks(Block b) {
|
||||||
|
@ -96,10 +96,6 @@ public class GoldPan extends SimpleSlimefunItem<ItemUseHandler> implements Recip
|
|||||||
for (GoldPanDrop setting : drops) {
|
for (GoldPanDrop setting : drops) {
|
||||||
randomizer.add(setting.getOutput(), setting.getValue());
|
randomizer.add(setting.getOutput(), setting.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (randomizer.sumWeights() < 100) {
|
|
||||||
randomizer.add(new ItemStack(Material.AIR), 100 - randomizer.sumWeights());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -110,7 +106,10 @@ public class GoldPan extends SimpleSlimefunItem<ItemUseHandler> implements Recip
|
|||||||
*/
|
*/
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public ItemStack getRandomOutput() {
|
public ItemStack getRandomOutput() {
|
||||||
return randomizer.getRandom();
|
ItemStack item = randomizer.getRandom();
|
||||||
|
|
||||||
|
// Fixes #2804
|
||||||
|
return item != null ? item : new ItemStack(Material.AIR);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -126,12 +125,14 @@ public class GoldPan extends SimpleSlimefunItem<ItemUseHandler> implements Recip
|
|||||||
if (block.isPresent()) {
|
if (block.isPresent()) {
|
||||||
Block b = block.get();
|
Block b = block.get();
|
||||||
|
|
||||||
|
// Check the clicked block type and for protections
|
||||||
if (b.getType() == getTargetMaterial() && SlimefunPlugin.getProtectionManager().hasPermission(e.getPlayer(), b.getLocation(), ProtectableAction.BREAK_BLOCK)) {
|
if (b.getType() == getTargetMaterial() && SlimefunPlugin.getProtectionManager().hasPermission(e.getPlayer(), b.getLocation(), ProtectableAction.BREAK_BLOCK)) {
|
||||||
ItemStack output = getRandomOutput();
|
ItemStack output = getRandomOutput();
|
||||||
|
|
||||||
b.getWorld().playEffect(b.getLocation(), Effect.STEP_SOUND, b.getType());
|
b.getWorld().playEffect(b.getLocation(), Effect.STEP_SOUND, b.getType());
|
||||||
b.setType(Material.AIR);
|
b.setType(Material.AIR);
|
||||||
|
|
||||||
|
// Make sure that the randomly selected item is not air
|
||||||
if (output.getType() != Material.AIR) {
|
if (output.getType() != Material.AIR) {
|
||||||
b.getWorld().dropItemNaturally(b.getLocation(), output.clone());
|
b.getWorld().dropItemNaturally(b.getLocation(), output.clone());
|
||||||
}
|
}
|
||||||
@ -148,6 +149,7 @@ public class GoldPan extends SimpleSlimefunItem<ItemUseHandler> implements Recip
|
|||||||
*
|
*
|
||||||
* @return the {@link EntityInteractHandler} of this {@link SlimefunItem}
|
* @return the {@link EntityInteractHandler} of this {@link SlimefunItem}
|
||||||
*/
|
*/
|
||||||
|
@Nonnull
|
||||||
public EntityInteractHandler onEntityInteract() {
|
public EntityInteractHandler onEntityInteract() {
|
||||||
return (e, item, offHand) -> {
|
return (e, item, offHand) -> {
|
||||||
if (!(e.getRightClicked() instanceof ItemFrame)) {
|
if (!(e.getRightClicked() instanceof ItemFrame)) {
|
||||||
|
@ -41,7 +41,6 @@ import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
|
|||||||
import io.github.thebusybiscuit.slimefun4.utils.itemstack.ItemStackWrapper;
|
import io.github.thebusybiscuit.slimefun4.utils.itemstack.ItemStackWrapper;
|
||||||
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
|
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
|
||||||
import me.mrCookieSlime.Slimefun.api.BlockStorage;
|
import me.mrCookieSlime.Slimefun.api.BlockStorage;
|
||||||
import me.mrCookieSlime.Slimefun.api.Slimefun;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This {@link Listener} is responsible for providing the core mechanics of the {@link AncientAltar}
|
* This {@link Listener} is responsible for providing the core mechanics of the {@link AncientAltar}
|
||||||
@ -105,12 +104,13 @@ public class AncientAltarListener implements Listener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String id = slimefunBlock.get().getId();
|
String id = slimefunBlock.get().getId();
|
||||||
|
Player p = e.getPlayer();
|
||||||
|
|
||||||
if (id.equals(pedestalItem.getId())) {
|
if (id.equals(pedestalItem.getId())) {
|
||||||
e.cancel();
|
e.cancel();
|
||||||
usePedestal(b, e.getPlayer());
|
usePedestal(b, p);
|
||||||
} else if (id.equals(altarItem.getId())) {
|
} else if (id.equals(altarItem.getId())) {
|
||||||
if (!Slimefun.hasUnlocked(e.getPlayer(), altarItem, true) || altarsInUse.contains(b.getLocation())) {
|
if (!altarItem.canUse(p, true) || altarsInUse.contains(b.getLocation())) {
|
||||||
e.cancel();
|
e.cancel();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -119,7 +119,7 @@ public class AncientAltarListener implements Listener {
|
|||||||
altarsInUse.add(b.getLocation());
|
altarsInUse.add(b.getLocation());
|
||||||
e.cancel();
|
e.cancel();
|
||||||
|
|
||||||
useAltar(b, e.getPlayer());
|
useAltar(b, p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -212,8 +212,9 @@ public class AncientAltarListener implements Listener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Optional<ItemStack> result = getRecipeOutput(catalyst, input);
|
Optional<ItemStack> result = getRecipeOutput(catalyst, input);
|
||||||
|
|
||||||
if (result.isPresent()) {
|
if (result.isPresent()) {
|
||||||
if (Slimefun.hasUnlocked(p, result.get(), true)) {
|
if (SlimefunUtils.canPlayerUseItem(p, result.get(), true)) {
|
||||||
List<ItemStack> consumed = new ArrayList<>();
|
List<ItemStack> consumed = new ArrayList<>();
|
||||||
consumed.add(catalyst);
|
consumed.add(catalyst);
|
||||||
|
|
||||||
@ -248,7 +249,7 @@ public class AncientAltarListener implements Listener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||||
public void onBlockPlace(BlockPlaceEvent e) {
|
public void onBlockPlace(BlockPlaceEvent e) {
|
||||||
if (altarItem == null || altarItem.isDisabled()) {
|
if (altarItem == null || altarItem.isDisabled()) {
|
||||||
return;
|
return;
|
||||||
|
@ -31,7 +31,6 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
|||||||
import io.github.thebusybiscuit.slimefun4.implementation.items.backpacks.Cooler;
|
import io.github.thebusybiscuit.slimefun4.implementation.items.backpacks.Cooler;
|
||||||
import io.github.thebusybiscuit.slimefun4.implementation.items.backpacks.SlimefunBackpack;
|
import io.github.thebusybiscuit.slimefun4.implementation.items.backpacks.SlimefunBackpack;
|
||||||
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
|
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
|
||||||
import me.mrCookieSlime.Slimefun.api.Slimefun;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This {@link Listener} is responsible for all events centered around a {@link SlimefunBackpack}.
|
* This {@link Listener} is responsible for all events centered around a {@link SlimefunBackpack}.
|
||||||
@ -122,7 +121,7 @@ public class BackpackListener implements Listener {
|
|||||||
@ParametersAreNonnullByDefault
|
@ParametersAreNonnullByDefault
|
||||||
public void openBackpack(Player p, ItemStack item, SlimefunBackpack backpack) {
|
public void openBackpack(Player p, ItemStack item, SlimefunBackpack backpack) {
|
||||||
if (item.getAmount() == 1) {
|
if (item.getAmount() == 1) {
|
||||||
if (Slimefun.hasUnlocked(p, backpack, true) && !PlayerProfile.get(p, profile -> openBackpack(p, item, profile, backpack.getSize()))) {
|
if (backpack.canUse(p, true) && !PlayerProfile.get(p, profile -> openBackpack(p, item, profile, backpack.getSize()))) {
|
||||||
SlimefunPlugin.getLocalization().sendMessage(p, "messages.opening-backpack");
|
SlimefunPlugin.getLocalization().sendMessage(p, "messages.opening-backpack");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -11,7 +11,6 @@ import org.bukkit.inventory.ItemStack;
|
|||||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||||
import io.github.thebusybiscuit.slimefun4.implementation.items.magical.BeeWings;
|
import io.github.thebusybiscuit.slimefun4.implementation.items.magical.BeeWings;
|
||||||
import io.github.thebusybiscuit.slimefun4.implementation.tasks.BeeWingsTask;
|
import io.github.thebusybiscuit.slimefun4.implementation.tasks.BeeWingsTask;
|
||||||
import me.mrCookieSlime.Slimefun.api.Slimefun;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This {@link Listener} is responsible for the slow falling effect given to the {@link Player}
|
* This {@link Listener} is responsible for the slow falling effect given to the {@link Player}
|
||||||
@ -44,7 +43,7 @@ public class BeeWingsListener implements Listener {
|
|||||||
Player player = (Player) e.getEntity();
|
Player player = (Player) e.getEntity();
|
||||||
ItemStack chestplate = player.getInventory().getChestplate();
|
ItemStack chestplate = player.getInventory().getChestplate();
|
||||||
|
|
||||||
if (wings.isItem(chestplate) && Slimefun.hasUnlocked(player, chestplate, true)) {
|
if (wings.isItem(chestplate) && wings.canUse(player, true)) {
|
||||||
new BeeWingsTask(player).scheduleRepeating(3, 1);
|
new BeeWingsTask(player).scheduleRepeating(3, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -56,14 +56,9 @@ public class BlockListener implements Listener {
|
|||||||
|
|
||||||
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
||||||
public void onBlockPlaceExisting(BlockPlaceEvent e) {
|
public void onBlockPlaceExisting(BlockPlaceEvent e) {
|
||||||
/*
|
|
||||||
* This prevents Players from placing a block where another block already exists.
|
|
||||||
* While this can cause ghost blocks it also prevents them from replacing grass
|
|
||||||
* or saplings etc...
|
|
||||||
*/
|
|
||||||
Block block = e.getBlock();
|
Block block = e.getBlock();
|
||||||
|
|
||||||
// Fixes #2636
|
// Fixes #2636 - This will solve the "ghost blocks" issue
|
||||||
if (e.getBlockReplacedState().getType().isAir()) {
|
if (e.getBlockReplacedState().getType().isAir()) {
|
||||||
SlimefunItem sfItem = BlockStorage.check(block);
|
SlimefunItem sfItem = BlockStorage.check(block);
|
||||||
|
|
||||||
@ -77,6 +72,7 @@ public class BlockListener implements Listener {
|
|||||||
BlockStorage.clearBlockInfo(block);
|
BlockStorage.clearBlockInfo(block);
|
||||||
}
|
}
|
||||||
} else if (BlockStorage.hasBlockInfo(e.getBlock())) {
|
} else if (BlockStorage.hasBlockInfo(e.getBlock())) {
|
||||||
|
// If there is no air (e.g. grass) then don't let the block be placed
|
||||||
e.setCancelled(true);
|
e.setCancelled(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -87,7 +83,7 @@ public class BlockListener implements Listener {
|
|||||||
SlimefunItem sfItem = SlimefunItem.getByItem(item);
|
SlimefunItem sfItem = SlimefunItem.getByItem(item);
|
||||||
|
|
||||||
if (sfItem != null && !(sfItem instanceof NotPlaceable) && Slimefun.isEnabled(e.getPlayer(), sfItem, true)) {
|
if (sfItem != null && !(sfItem instanceof NotPlaceable) && Slimefun.isEnabled(e.getPlayer(), sfItem, true)) {
|
||||||
if (!Slimefun.hasUnlocked(e.getPlayer(), sfItem, true)) {
|
if (!sfItem.canUse(e.getPlayer(), true)) {
|
||||||
e.setCancelled(true);
|
e.setCancelled(true);
|
||||||
} else {
|
} else {
|
||||||
if (SlimefunPlugin.getBlockDataService().isTileEntity(e.getBlock().getType())) {
|
if (SlimefunPlugin.getBlockDataService().isTileEntity(e.getBlock().getType())) {
|
||||||
@ -117,18 +113,18 @@ public class BlockListener implements Listener {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
checkForSensitiveBlockAbove(e.getPlayer(), e.getBlock());
|
|
||||||
|
|
||||||
ItemStack item = e.getPlayer().getInventory().getItemInMainHand();
|
ItemStack item = e.getPlayer().getInventory().getItemInMainHand();
|
||||||
|
checkForSensitiveBlockAbove(e, item);
|
||||||
|
|
||||||
int fortune = getBonusDropsWithFortune(item, e.getBlock());
|
int fortune = getBonusDropsWithFortune(item, e.getBlock());
|
||||||
List<ItemStack> drops = new ArrayList<>();
|
List<ItemStack> drops = new ArrayList<>();
|
||||||
|
|
||||||
if (!item.getType().isAir()) {
|
if (!e.isCancelled() && !item.getType().isAir()) {
|
||||||
callToolHandler(e, item, fortune, drops);
|
callToolHandler(e, item, fortune, drops);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!e.isCancelled()) {
|
if (!e.isCancelled()) {
|
||||||
callBlockHandler(e, item, fortune, drops);
|
callBlockHandler(e, item, drops);
|
||||||
}
|
}
|
||||||
|
|
||||||
dropItems(e, drops);
|
dropItems(e, drops);
|
||||||
@ -139,7 +135,7 @@ public class BlockListener implements Listener {
|
|||||||
SlimefunItem tool = SlimefunItem.getByItem(item);
|
SlimefunItem tool = SlimefunItem.getByItem(item);
|
||||||
|
|
||||||
if (tool != null) {
|
if (tool != null) {
|
||||||
if (Slimefun.hasUnlocked(e.getPlayer(), tool, true)) {
|
if (tool.canUse(e.getPlayer(), true)) {
|
||||||
tool.callItemHandler(ToolUseHandler.class, handler -> handler.onToolUse(e, item, fortune, drops));
|
tool.callItemHandler(ToolUseHandler.class, handler -> handler.onToolUse(e, item, fortune, drops));
|
||||||
} else {
|
} else {
|
||||||
e.setCancelled(true);
|
e.setCancelled(true);
|
||||||
@ -148,7 +144,7 @@ public class BlockListener implements Listener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@ParametersAreNonnullByDefault
|
@ParametersAreNonnullByDefault
|
||||||
private void callBlockHandler(BlockBreakEvent e, ItemStack item, int fortune, List<ItemStack> drops) {
|
private void callBlockHandler(BlockBreakEvent e, ItemStack item, List<ItemStack> drops) {
|
||||||
SlimefunItem sfItem = BlockStorage.check(e.getBlock());
|
SlimefunItem sfItem = BlockStorage.check(e.getBlock());
|
||||||
|
|
||||||
if (sfItem == null && SlimefunPlugin.getBlockDataService().isTileEntity(e.getBlock().getType())) {
|
if (sfItem == null && SlimefunPlugin.getBlockDataService().isTileEntity(e.getBlock().getType())) {
|
||||||
@ -172,7 +168,7 @@ public class BlockListener implements Listener {
|
|||||||
sfItem.error("Something went wrong while triggering a BlockHandler", x);
|
sfItem.error("Something went wrong while triggering a BlockHandler", x);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
sfItem.callItemHandler(BlockBreakHandler.class, handler -> handler.onBlockBreak(e, item, fortune, drops));
|
sfItem.callItemHandler(BlockBreakHandler.class, handler -> handler.onPlayerBreak(e, item, drops));
|
||||||
}
|
}
|
||||||
|
|
||||||
drops.addAll(sfItem.getDrops());
|
drops.addAll(sfItem.getDrops());
|
||||||
@ -182,13 +178,15 @@ public class BlockListener implements Listener {
|
|||||||
|
|
||||||
@ParametersAreNonnullByDefault
|
@ParametersAreNonnullByDefault
|
||||||
private void dropItems(BlockBreakEvent e, List<ItemStack> drops) {
|
private void dropItems(BlockBreakEvent e, List<ItemStack> drops) {
|
||||||
if (!drops.isEmpty()) {
|
if (!drops.isEmpty() && !e.isCancelled()) {
|
||||||
e.getBlock().setType(Material.AIR);
|
|
||||||
|
|
||||||
// Notify plugins like CoreProtect
|
// Notify plugins like CoreProtect
|
||||||
SlimefunPlugin.getProtectionManager().logAction(e.getPlayer(), e.getBlock(), ProtectableAction.BREAK_BLOCK);
|
SlimefunPlugin.getProtectionManager().logAction(e.getPlayer(), e.getBlock(), ProtectableAction.BREAK_BLOCK);
|
||||||
|
|
||||||
|
// Fixes #2560
|
||||||
if (e.isDropItems()) {
|
if (e.isDropItems()) {
|
||||||
|
// Disable normal block drops
|
||||||
|
e.setDropItems(false);
|
||||||
|
|
||||||
for (ItemStack drop : drops) {
|
for (ItemStack drop : drops) {
|
||||||
if (drop != null && drop.getType() != Material.AIR) {
|
if (drop != null && drop.getType() != Material.AIR) {
|
||||||
e.getBlock().getWorld().dropItemNaturally(e.getBlock().getLocation(), drop);
|
e.getBlock().getWorld().dropItemNaturally(e.getBlock().getLocation(), drop);
|
||||||
@ -209,8 +207,8 @@ public class BlockListener implements Listener {
|
|||||||
* The {@link Block} that was broken
|
* The {@link Block} that was broken
|
||||||
*/
|
*/
|
||||||
@ParametersAreNonnullByDefault
|
@ParametersAreNonnullByDefault
|
||||||
private void checkForSensitiveBlockAbove(Player p, Block b) {
|
private void checkForSensitiveBlockAbove(BlockBreakEvent e, ItemStack item) {
|
||||||
Block blockAbove = b.getRelative(BlockFace.UP);
|
Block blockAbove = e.getBlock().getRelative(BlockFace.UP);
|
||||||
|
|
||||||
if (SlimefunTag.SENSITIVE_MATERIALS.isTagged(blockAbove.getType())) {
|
if (SlimefunTag.SENSITIVE_MATERIALS.isTagged(blockAbove.getType())) {
|
||||||
SlimefunItem sfItem = BlockStorage.check(blockAbove);
|
SlimefunItem sfItem = BlockStorage.check(blockAbove);
|
||||||
@ -219,13 +217,29 @@ public class BlockListener implements Listener {
|
|||||||
SlimefunBlockHandler blockHandler = SlimefunPlugin.getRegistry().getBlockHandlers().get(sfItem.getId());
|
SlimefunBlockHandler blockHandler = SlimefunPlugin.getRegistry().getBlockHandlers().get(sfItem.getId());
|
||||||
|
|
||||||
if (blockHandler != null) {
|
if (blockHandler != null) {
|
||||||
if (blockHandler.onBreak(p, blockAbove, sfItem, UnregisterReason.PLAYER_BREAK)) {
|
if (blockHandler.onBreak(e.getPlayer(), blockAbove, sfItem, UnregisterReason.PLAYER_BREAK)) {
|
||||||
blockAbove.getWorld().dropItemNaturally(blockAbove.getLocation(), BlockStorage.retrieve(blockAbove));
|
blockAbove.getWorld().dropItemNaturally(blockAbove.getLocation(), BlockStorage.retrieve(blockAbove));
|
||||||
blockAbove.setType(Material.AIR);
|
blockAbove.setType(Material.AIR);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
blockAbove.getWorld().dropItemNaturally(blockAbove.getLocation(), BlockStorage.retrieve(blockAbove));
|
/*
|
||||||
|
* We create a dummy here to pass onto the BlockBreakHandler.
|
||||||
|
* This will set the correct block context.
|
||||||
|
*/
|
||||||
|
BlockBreakEvent dummyEvent = new BlockBreakEvent(blockAbove, e.getPlayer());
|
||||||
|
List<ItemStack> drops = new ArrayList<>();
|
||||||
|
drops.addAll(sfItem.getDrops(e.getPlayer()));
|
||||||
|
|
||||||
|
sfItem.callItemHandler(BlockBreakHandler.class, handler -> handler.onPlayerBreak(dummyEvent, item, drops));
|
||||||
blockAbove.setType(Material.AIR);
|
blockAbove.setType(Material.AIR);
|
||||||
|
|
||||||
|
if (!dummyEvent.isCancelled() && dummyEvent.isDropItems()) {
|
||||||
|
for (ItemStack drop : drops) {
|
||||||
|
if (drop != null && drop.getType() != Material.AIR) {
|
||||||
|
blockAbove.getWorld().dropItemNaturally(blockAbove.getLocation(), drop);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -84,9 +84,10 @@ public class BlockPhysicsListener implements Listener {
|
|||||||
@EventHandler(ignoreCancelled = true)
|
@EventHandler(ignoreCancelled = true)
|
||||||
public void onLiquidFlow(BlockFromToEvent e) {
|
public void onLiquidFlow(BlockFromToEvent e) {
|
||||||
Block block = e.getToBlock();
|
Block block = e.getToBlock();
|
||||||
|
Material type = block.getType();
|
||||||
|
|
||||||
// Check if this Material can be destroyed by fluids
|
// Check if this Material can be destroyed by fluids
|
||||||
if (SlimefunTag.FLUID_SENSITIVE_MATERIALS.isTagged(block.getType())) {
|
if (SlimefunTag.FLUID_SENSITIVE_MATERIALS.isTagged(type)) {
|
||||||
// Check if this Block holds any data
|
// Check if this Block holds any data
|
||||||
if (BlockStorage.hasBlockInfo(block)) {
|
if (BlockStorage.hasBlockInfo(block)) {
|
||||||
e.setCancelled(true);
|
e.setCancelled(true);
|
||||||
|
@ -21,7 +21,6 @@ import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile;
|
|||||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||||
import io.github.thebusybiscuit.slimefun4.implementation.items.backpacks.Cooler;
|
import io.github.thebusybiscuit.slimefun4.implementation.items.backpacks.Cooler;
|
||||||
import io.github.thebusybiscuit.slimefun4.implementation.items.food.Juice;
|
import io.github.thebusybiscuit.slimefun4.implementation.items.food.Juice;
|
||||||
import me.mrCookieSlime.Slimefun.api.Slimefun;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This {@link Listener} listens for a {@link FoodLevelChangeEvent} or an {@link EntityDamageEvent} for starvation
|
* This {@link Listener} listens for a {@link FoodLevelChangeEvent} or an {@link EntityDamageEvent} for starvation
|
||||||
@ -74,7 +73,7 @@ public class CoolerListener implements Listener {
|
|||||||
|
|
||||||
for (ItemStack item : p.getInventory().getContents()) {
|
for (ItemStack item : p.getInventory().getContents()) {
|
||||||
if (cooler.isItem(item)) {
|
if (cooler.isItem(item)) {
|
||||||
if (Slimefun.hasUnlocked(p, cooler, true)) {
|
if (cooler.canUse(p, true)) {
|
||||||
takeJuiceFromCooler(p, item);
|
takeJuiceFromCooler(p, item);
|
||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
|
@ -18,7 +18,6 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
|||||||
import io.github.thebusybiscuit.slimefun4.implementation.items.armor.ElytraCap;
|
import io.github.thebusybiscuit.slimefun4.implementation.items.armor.ElytraCap;
|
||||||
import io.github.thebusybiscuit.slimefun4.implementation.items.armor.SlimefunArmorPiece;
|
import io.github.thebusybiscuit.slimefun4.implementation.items.armor.SlimefunArmorPiece;
|
||||||
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
|
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
|
||||||
import me.mrCookieSlime.Slimefun.api.Slimefun;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@link Listener} for the {@link ElytraCap}.
|
* The {@link Listener} for the {@link ElytraCap}.
|
||||||
@ -57,7 +56,7 @@ public class ElytraImpactListener implements Listener {
|
|||||||
if (helmet.isPresent()) {
|
if (helmet.isPresent()) {
|
||||||
SlimefunItem item = helmet.get();
|
SlimefunItem item = helmet.get();
|
||||||
|
|
||||||
if (Slimefun.hasUnlocked(p, item, true) && profile.hasFullProtectionAgainst(ProtectionType.FLYING_INTO_WALL)) {
|
if (item.canUse(p, true) && profile.hasFullProtectionAgainst(ProtectionType.FLYING_INTO_WALL)) {
|
||||||
e.setDamage(0);
|
e.setDamage(0);
|
||||||
p.playSound(p.getLocation(), Sound.BLOCK_STONE_HIT, 20, 1);
|
p.playSound(p.getLocation(), Sound.BLOCK_STONE_HIT, 20, 1);
|
||||||
|
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
package io.github.thebusybiscuit.slimefun4.implementation.listeners;
|
package io.github.thebusybiscuit.slimefun4.implementation.listeners;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
@ -9,15 +11,29 @@ import org.bukkit.block.Block;
|
|||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.EventPriority;
|
import org.bukkit.event.EventPriority;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.block.BlockExplodeEvent;
|
||||||
import org.bukkit.event.entity.EntityExplodeEvent;
|
import org.bukkit.event.entity.EntityExplodeEvent;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
import io.github.thebusybiscuit.slimefun4.core.attributes.WitherProof;
|
import io.github.thebusybiscuit.slimefun4.core.attributes.WitherProof;
|
||||||
|
import io.github.thebusybiscuit.slimefun4.core.handlers.BlockBreakHandler;
|
||||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||||
import me.mrCookieSlime.Slimefun.Objects.SlimefunBlockHandler;
|
import me.mrCookieSlime.Slimefun.Objects.SlimefunBlockHandler;
|
||||||
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
|
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
|
||||||
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.UnregisterReason;
|
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.UnregisterReason;
|
||||||
import me.mrCookieSlime.Slimefun.api.BlockStorage;
|
import me.mrCookieSlime.Slimefun.api.BlockStorage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link ExplosionsListener} is a {@link Listener} which listens to any explosion events.
|
||||||
|
* Any {@link WitherProof} block is excluded from these explosions and this {@link Listener} also
|
||||||
|
* calls the explosive part of the {@link BlockBreakHandler}.
|
||||||
|
*
|
||||||
|
* @author TheBusyBiscuit
|
||||||
|
*
|
||||||
|
* @see BlockBreakHandler
|
||||||
|
* @see WitherProof
|
||||||
|
*
|
||||||
|
*/
|
||||||
public class ExplosionsListener implements Listener {
|
public class ExplosionsListener implements Listener {
|
||||||
|
|
||||||
public ExplosionsListener(@Nonnull SlimefunPlugin plugin) {
|
public ExplosionsListener(@Nonnull SlimefunPlugin plugin) {
|
||||||
@ -26,12 +42,19 @@ public class ExplosionsListener implements Listener {
|
|||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
public void onEntityExplode(EntityExplodeEvent e) {
|
public void onEntityExplode(EntityExplodeEvent e) {
|
||||||
Iterator<Block> blocks = e.blockList().iterator();
|
removeResistantBlocks(e.blockList().iterator());
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
|
public void onBlockExplode(BlockExplodeEvent e) {
|
||||||
|
removeResistantBlocks(e.blockList().iterator());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeResistantBlocks(@Nonnull Iterator<Block> blocks) {
|
||||||
while (blocks.hasNext()) {
|
while (blocks.hasNext()) {
|
||||||
Block block = blocks.next();
|
Block block = blocks.next();
|
||||||
|
|
||||||
SlimefunItem item = BlockStorage.check(block);
|
SlimefunItem item = BlockStorage.check(block);
|
||||||
|
|
||||||
if (item != null) {
|
if (item != null) {
|
||||||
blocks.remove();
|
blocks.remove();
|
||||||
|
|
||||||
@ -41,6 +64,24 @@ public class ExplosionsListener implements Listener {
|
|||||||
|
|
||||||
if (blockHandler != null) {
|
if (blockHandler != null) {
|
||||||
success = blockHandler.onBreak(null, block, item, UnregisterReason.EXPLODE);
|
success = blockHandler.onBreak(null, block, item, UnregisterReason.EXPLODE);
|
||||||
|
} else {
|
||||||
|
item.callItemHandler(BlockBreakHandler.class, handler -> {
|
||||||
|
if (handler.isExplosionAllowed(block)) {
|
||||||
|
BlockStorage.clearBlockInfo(block);
|
||||||
|
block.setType(Material.AIR);
|
||||||
|
|
||||||
|
List<ItemStack> drops = new ArrayList<>();
|
||||||
|
handler.onExplode(block, drops);
|
||||||
|
|
||||||
|
for (ItemStack drop : drops) {
|
||||||
|
if (drop != null && !drop.getType().isAir()) {
|
||||||
|
block.getWorld().dropItemNaturally(block.getLocation(), drop);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
|
@ -14,13 +14,12 @@ import io.github.thebusybiscuit.slimefun4.implementation.items.armor.Parachute;
|
|||||||
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.gadgets.JetBoots;
|
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.gadgets.JetBoots;
|
||||||
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.gadgets.Jetpack;
|
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.gadgets.Jetpack;
|
||||||
import io.github.thebusybiscuit.slimefun4.implementation.items.magical.InfusedMagnet;
|
import io.github.thebusybiscuit.slimefun4.implementation.items.magical.InfusedMagnet;
|
||||||
|
import io.github.thebusybiscuit.slimefun4.implementation.tasks.InfusedMagnetTask;
|
||||||
import io.github.thebusybiscuit.slimefun4.implementation.tasks.JetBootsTask;
|
import io.github.thebusybiscuit.slimefun4.implementation.tasks.JetBootsTask;
|
||||||
import io.github.thebusybiscuit.slimefun4.implementation.tasks.JetpackTask;
|
import io.github.thebusybiscuit.slimefun4.implementation.tasks.JetpackTask;
|
||||||
import io.github.thebusybiscuit.slimefun4.implementation.tasks.InfusedMagnetTask;
|
|
||||||
import io.github.thebusybiscuit.slimefun4.implementation.tasks.ParachuteTask;
|
import io.github.thebusybiscuit.slimefun4.implementation.tasks.ParachuteTask;
|
||||||
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
|
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
|
||||||
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
|
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
|
||||||
import me.mrCookieSlime.Slimefun.api.Slimefun;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This {@link Listener} is responsible for listening to the {@link PlayerToggleSneakEvent}
|
* This {@link Listener} is responsible for listening to the {@link PlayerToggleSneakEvent}
|
||||||
@ -59,7 +58,7 @@ public class GadgetsListener implements Listener {
|
|||||||
if (SlimefunUtils.containsSimilarItem(p.getInventory(), SlimefunItems.INFUSED_MAGNET, true)) {
|
if (SlimefunUtils.containsSimilarItem(p.getInventory(), SlimefunItems.INFUSED_MAGNET, true)) {
|
||||||
InfusedMagnet magnet = (InfusedMagnet) SlimefunItems.INFUSED_MAGNET.getItem();
|
InfusedMagnet magnet = (InfusedMagnet) SlimefunItems.INFUSED_MAGNET.getItem();
|
||||||
|
|
||||||
if (Slimefun.hasUnlocked(p, magnet, true)) {
|
if (magnet.canUse(p, true)) {
|
||||||
new InfusedMagnetTask(p, magnet.getRadius()).scheduleRepeating(0, 8);
|
new InfusedMagnetTask(p, magnet.getRadius()).scheduleRepeating(0, 8);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -67,7 +66,7 @@ public class GadgetsListener implements Listener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void handleChestplate(@Nonnull Player p, @Nullable SlimefunItem chestplate) {
|
private void handleChestplate(@Nonnull Player p, @Nullable SlimefunItem chestplate) {
|
||||||
if (chestplate == null || !Slimefun.hasUnlocked(p, chestplate, true)) {
|
if (chestplate == null || !chestplate.canUse(p, true)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,7 +82,7 @@ public class GadgetsListener implements Listener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void handleBoots(@Nonnull Player p, @Nullable SlimefunItem boots) {
|
private void handleBoots(@Nonnull Player p, @Nullable SlimefunItem boots) {
|
||||||
if (boots instanceof JetBoots && Slimefun.hasUnlocked(p, boots, true)) {
|
if (boots instanceof JetBoots && boots.canUse(p, true)) {
|
||||||
double speed = ((JetBoots) boots).getSpeed();
|
double speed = ((JetBoots) boots).getSpeed();
|
||||||
|
|
||||||
if (speed > 0.2) {
|
if (speed > 0.2) {
|
||||||
|
@ -0,0 +1,45 @@
|
|||||||
|
package io.github.thebusybiscuit.slimefun4.implementation.listeners;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
|
||||||
|
import io.github.thebusybiscuit.slimefun4.api.events.AndroidMineEvent;
|
||||||
|
import io.github.thebusybiscuit.slimefun4.core.handlers.BlockBreakHandler;
|
||||||
|
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||||
|
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
|
||||||
|
import me.mrCookieSlime.Slimefun.api.BlockStorage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This {@link Listener} makes sure that an {@link AndroidMineEvent} gets properly propagated
|
||||||
|
* to the {@link BlockBreakHandler#onAndroidBreak(AndroidMineEvent)} method of a placed block.
|
||||||
|
* If that block is a {@link SlimefunItem} of course.
|
||||||
|
*
|
||||||
|
* @author TheBusyBiscuit
|
||||||
|
*
|
||||||
|
* @see BlockBreakHandler
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class MiningAndroidListener implements Listener {
|
||||||
|
|
||||||
|
public MiningAndroidListener(@Nonnull SlimefunPlugin plugin) {
|
||||||
|
plugin.getServer().getPluginManager().registerEvents(this, plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(ignoreCancelled = true)
|
||||||
|
public void onAndroidMine(AndroidMineEvent e) {
|
||||||
|
SlimefunItem slimefunItem = BlockStorage.check(e.getBlock());
|
||||||
|
|
||||||
|
// Fixes #2839 - Can't believe we forgot a null check here
|
||||||
|
if (slimefunItem != null) {
|
||||||
|
slimefunItem.callItemHandler(BlockBreakHandler.class, handler -> {
|
||||||
|
if (handler.isAndroidAllowed(e.getBlock())) {
|
||||||
|
handler.onAndroidBreak(e);
|
||||||
|
} else {
|
||||||
|
e.setCancelled(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -62,8 +62,13 @@ public class MultiBlockListener implements Listener {
|
|||||||
e.setCancelled(true);
|
e.setCancelled(true);
|
||||||
|
|
||||||
MultiBlock mb = multiblocks.getLast();
|
MultiBlock mb = multiblocks.getLast();
|
||||||
|
MultiBlockInteractEvent event = new MultiBlockInteractEvent(p, mb, b, e.getBlockFace());
|
||||||
|
Bukkit.getPluginManager().callEvent(event);
|
||||||
|
|
||||||
|
// Fixes #2809
|
||||||
|
if (!event.isCancelled()) {
|
||||||
mb.getSlimefunItem().callItemHandler(MultiBlockInteractionHandler.class, handler -> handler.onInteract(p, mb, b));
|
mb.getSlimefunItem().callItemHandler(MultiBlockInteractionHandler.class, handler -> handler.onInteract(p, mb, b));
|
||||||
Bukkit.getPluginManager().callEvent(new MultiBlockInteractEvent(p, mb, b, e.getBlockFace()));
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,7 +23,6 @@ import io.github.thebusybiscuit.slimefun4.implementation.items.armor.LongFallBoo
|
|||||||
import io.github.thebusybiscuit.slimefun4.implementation.items.armor.SlimefunArmorPiece;
|
import io.github.thebusybiscuit.slimefun4.implementation.items.armor.SlimefunArmorPiece;
|
||||||
import io.github.thebusybiscuit.slimefun4.implementation.items.armor.StomperBoots;
|
import io.github.thebusybiscuit.slimefun4.implementation.items.armor.StomperBoots;
|
||||||
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
|
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
|
||||||
import me.mrCookieSlime.Slimefun.api.Slimefun;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This {@link Listener} is responsible for handling all boots provided by
|
* This {@link Listener} is responsible for handling all boots provided by
|
||||||
@ -53,7 +52,7 @@ public class SlimefunBootsListener implements Listener {
|
|||||||
Player p = (Player) e.getEntity();
|
Player p = (Player) e.getEntity();
|
||||||
SlimefunItem boots = SlimefunItem.getByItem(p.getInventory().getBoots());
|
SlimefunItem boots = SlimefunItem.getByItem(p.getInventory().getBoots());
|
||||||
|
|
||||||
if (boots instanceof EnderBoots && Slimefun.hasUnlocked(p, boots, true)) {
|
if (boots instanceof EnderBoots && boots.canUse(p, true)) {
|
||||||
e.setCancelled(true);
|
e.setCancelled(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -65,7 +64,7 @@ public class SlimefunBootsListener implements Listener {
|
|||||||
|
|
||||||
if (boots != null) {
|
if (boots != null) {
|
||||||
// Check if the boots were researched
|
// Check if the boots were researched
|
||||||
if (!Slimefun.hasUnlocked(p, boots, true)) {
|
if (!boots.canUse(p, true)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,7 +90,7 @@ public class SlimefunBootsListener implements Listener {
|
|||||||
Player p = e.getPlayer();
|
Player p = e.getPlayer();
|
||||||
SlimefunItem boots = SlimefunItem.getByItem(p.getInventory().getBoots());
|
SlimefunItem boots = SlimefunItem.getByItem(p.getInventory().getBoots());
|
||||||
|
|
||||||
if (boots instanceof FarmerShoes && Slimefun.hasUnlocked(p, boots, true)) {
|
if (boots instanceof FarmerShoes && boots.canUse(p, true)) {
|
||||||
e.setCancelled(true);
|
e.setCancelled(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,6 @@ import org.bukkit.inventory.ItemStack;
|
|||||||
import io.github.thebusybiscuit.slimefun4.core.handlers.ItemConsumptionHandler;
|
import io.github.thebusybiscuit.slimefun4.core.handlers.ItemConsumptionHandler;
|
||||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||||
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
|
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
|
||||||
import me.mrCookieSlime.Slimefun.api.Slimefun;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This {@link Listener} is responsible for handling the {@link ItemConsumptionHandler}
|
* This {@link Listener} is responsible for handling the {@link ItemConsumptionHandler}
|
||||||
@ -33,7 +32,7 @@ public class SlimefunItemConsumeListener implements Listener {
|
|||||||
SlimefunItem sfItem = SlimefunItem.getByItem(item);
|
SlimefunItem sfItem = SlimefunItem.getByItem(item);
|
||||||
|
|
||||||
if (sfItem != null) {
|
if (sfItem != null) {
|
||||||
if (Slimefun.hasUnlocked(p, sfItem, true)) {
|
if (sfItem.canUse(p, true)) {
|
||||||
sfItem.callItemHandler(ItemConsumptionHandler.class, handler -> handler.onConsume(e, p, item));
|
sfItem.callItemHandler(ItemConsumptionHandler.class, handler -> handler.onConsume(e, p, item));
|
||||||
} else {
|
} else {
|
||||||
e.setCancelled(true);
|
e.setCancelled(true);
|
||||||
|
@ -25,7 +25,6 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
|||||||
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
|
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
|
||||||
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
|
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
|
||||||
import me.mrCookieSlime.Slimefun.api.BlockStorage;
|
import me.mrCookieSlime.Slimefun.api.BlockStorage;
|
||||||
import me.mrCookieSlime.Slimefun.api.Slimefun;
|
|
||||||
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu;
|
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu;
|
||||||
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset;
|
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset;
|
||||||
import me.mrCookieSlime.Slimefun.api.inventory.UniversalBlockMenu;
|
import me.mrCookieSlime.Slimefun.api.inventory.UniversalBlockMenu;
|
||||||
@ -94,8 +93,10 @@ public class SlimefunItemInteractListener implements Listener {
|
|||||||
Optional<SlimefunItem> optional = event.getSlimefunItem();
|
Optional<SlimefunItem> optional = event.getSlimefunItem();
|
||||||
|
|
||||||
if (optional.isPresent()) {
|
if (optional.isPresent()) {
|
||||||
if (Slimefun.hasUnlocked(e.getPlayer(), optional.get(), true)) {
|
SlimefunItem sfItem = optional.get();
|
||||||
return optional.get().callItemHandler(ItemUseHandler.class, handler -> handler.onRightClick(event));
|
|
||||||
|
if (sfItem.canUse(e.getPlayer(), true)) {
|
||||||
|
return sfItem.callItemHandler(ItemUseHandler.class, handler -> handler.onRightClick(event));
|
||||||
} else {
|
} else {
|
||||||
event.setUseItem(Result.DENY);
|
event.setUseItem(Result.DENY);
|
||||||
}
|
}
|
||||||
@ -109,19 +110,20 @@ public class SlimefunItemInteractListener implements Listener {
|
|||||||
Optional<SlimefunItem> optional = event.getSlimefunBlock();
|
Optional<SlimefunItem> optional = event.getSlimefunBlock();
|
||||||
|
|
||||||
if (optional.isPresent()) {
|
if (optional.isPresent()) {
|
||||||
if (!Slimefun.hasUnlocked(event.getPlayer(), optional.get(), true)) {
|
SlimefunItem sfItem = optional.get();
|
||||||
|
|
||||||
|
if (!sfItem.canUse(event.getPlayer(), true)) {
|
||||||
event.getInteractEvent().setCancelled(true);
|
event.getInteractEvent().setCancelled(true);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean interactable = optional.get().callItemHandler(BlockUseHandler.class, handler -> handler.onRightClick(event));
|
boolean interactable = sfItem.callItemHandler(BlockUseHandler.class, handler -> handler.onRightClick(event));
|
||||||
|
|
||||||
if (!interactable) {
|
if (!interactable) {
|
||||||
String id = optional.get().getId();
|
|
||||||
Player p = event.getPlayer();
|
Player p = event.getPlayer();
|
||||||
|
|
||||||
if (BlockMenuPreset.isInventory(id)) {
|
if (BlockMenuPreset.isInventory(sfItem.getId())) {
|
||||||
openInventory(p, id, event.getInteractEvent().getClickedBlock(), event);
|
openInventory(p, sfItem, event.getInteractEvent().getClickedBlock(), event);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -131,12 +133,13 @@ public class SlimefunItemInteractListener implements Listener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@ParametersAreNonnullByDefault
|
@ParametersAreNonnullByDefault
|
||||||
private void openInventory(Player p, String id, Block clickedBlock, PlayerRightClickEvent event) {
|
private void openInventory(Player p, SlimefunItem item, Block clickedBlock, PlayerRightClickEvent event) {
|
||||||
|
try {
|
||||||
if (!p.isSneaking() || event.getItem().getType() == Material.AIR) {
|
if (!p.isSneaking() || event.getItem().getType() == Material.AIR) {
|
||||||
event.getInteractEvent().setCancelled(true);
|
event.getInteractEvent().setCancelled(true);
|
||||||
|
|
||||||
if (BlockStorage.hasUniversalInventory(id)) {
|
if (BlockStorage.hasUniversalInventory(item.getId())) {
|
||||||
UniversalBlockMenu menu = BlockStorage.getUniversalInventory(id);
|
UniversalBlockMenu menu = BlockStorage.getUniversalInventory(item.getId());
|
||||||
|
|
||||||
if (menu.canOpen(clickedBlock, p)) {
|
if (menu.canOpen(clickedBlock, p)) {
|
||||||
menu.open(p);
|
menu.open(p);
|
||||||
@ -153,6 +156,9 @@ public class SlimefunItemInteractListener implements Listener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} catch (Exception | LinkageError x) {
|
||||||
|
item.error("An Exception was caught while trying to open the Inventory", x);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -61,24 +61,24 @@ public class TalismanListener implements Listener {
|
|||||||
public void onDamageGet(EntityDamageEvent e) {
|
public void onDamageGet(EntityDamageEvent e) {
|
||||||
if (e.getEntity() instanceof Player) {
|
if (e.getEntity() instanceof Player) {
|
||||||
if (e.getCause() == DamageCause.LAVA) {
|
if (e.getCause() == DamageCause.LAVA) {
|
||||||
Talisman.checkFor(e, SlimefunItems.TALISMAN_LAVA);
|
Talisman.trigger(e, SlimefunItems.TALISMAN_LAVA);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e.getCause() == DamageCause.DROWNING) {
|
if (e.getCause() == DamageCause.DROWNING) {
|
||||||
Talisman.checkFor(e, SlimefunItems.TALISMAN_WATER);
|
Talisman.trigger(e, SlimefunItems.TALISMAN_WATER);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e.getCause() == DamageCause.FALL) {
|
if (e.getCause() == DamageCause.FALL) {
|
||||||
Talisman.checkFor(e, SlimefunItems.TALISMAN_ANGEL);
|
Talisman.trigger(e, SlimefunItems.TALISMAN_ANGEL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e.getCause() == DamageCause.FIRE) {
|
if (e.getCause() == DamageCause.FIRE) {
|
||||||
Talisman.checkFor(e, SlimefunItems.TALISMAN_FIRE);
|
Talisman.trigger(e, SlimefunItems.TALISMAN_FIRE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e.getCause() == DamageCause.ENTITY_ATTACK) {
|
if (e.getCause() == DamageCause.ENTITY_ATTACK) {
|
||||||
Talisman.checkFor(e, SlimefunItems.TALISMAN_KNIGHT);
|
Talisman.trigger(e, SlimefunItems.TALISMAN_KNIGHT);
|
||||||
Talisman.checkFor(e, SlimefunItems.TALISMAN_WARRIOR);
|
Talisman.trigger(e, SlimefunItems.TALISMAN_WARRIOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e.getCause() == DamageCause.PROJECTILE && e instanceof EntityDamageByEntityEvent) {
|
if (e.getCause() == DamageCause.PROJECTILE && e instanceof EntityDamageByEntityEvent) {
|
||||||
@ -91,7 +91,7 @@ public class TalismanListener implements Listener {
|
|||||||
if (e.getDamager() instanceof Projectile && !(e.getDamager() instanceof Trident)) {
|
if (e.getDamager() instanceof Projectile && !(e.getDamager() instanceof Trident)) {
|
||||||
Projectile projectile = (Projectile) e.getDamager();
|
Projectile projectile = (Projectile) e.getDamager();
|
||||||
|
|
||||||
if (Talisman.checkFor(e, SlimefunItems.TALISMAN_WHIRLWIND)) {
|
if (Talisman.trigger(e, SlimefunItems.TALISMAN_WHIRLWIND)) {
|
||||||
Player p = (Player) e.getEntity();
|
Player p = (Player) e.getEntity();
|
||||||
returnProjectile(p, projectile);
|
returnProjectile(p, projectile);
|
||||||
}
|
}
|
||||||
@ -143,7 +143,7 @@ public class TalismanListener implements Listener {
|
|||||||
|
|
||||||
// We are also excluding entities which can pickup items, this is not perfect
|
// We are also excluding entities which can pickup items, this is not perfect
|
||||||
// but it at least prevents dupes by tossing items to zombies
|
// but it at least prevents dupes by tossing items to zombies
|
||||||
if (!entity.getCanPickupItems() && Talisman.checkFor(e, SlimefunItems.TALISMAN_HUNTER)) {
|
if (!entity.getCanPickupItems() && Talisman.trigger(e, SlimefunItems.TALISMAN_HUNTER)) {
|
||||||
Collection<ItemStack> extraDrops = getExtraDrops(e.getEntity(), e.getDrops());
|
Collection<ItemStack> extraDrops = getExtraDrops(e.getEntity(), e.getDrops());
|
||||||
|
|
||||||
for (ItemStack drop : extraDrops) {
|
for (ItemStack drop : extraDrops) {
|
||||||
@ -192,7 +192,7 @@ public class TalismanListener implements Listener {
|
|||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onItemBreak(PlayerItemBreakEvent e) {
|
public void onItemBreak(PlayerItemBreakEvent e) {
|
||||||
if (Talisman.checkFor(e, SlimefunItems.TALISMAN_ANVIL)) {
|
if (Talisman.trigger(e, SlimefunItems.TALISMAN_ANVIL)) {
|
||||||
PlayerInventory inv = e.getPlayer().getInventory();
|
PlayerInventory inv = e.getPlayer().getInventory();
|
||||||
int slot = inv.getHeldItemSlot();
|
int slot = inv.getHeldItemSlot();
|
||||||
|
|
||||||
@ -225,7 +225,7 @@ public class TalismanListener implements Listener {
|
|||||||
@EventHandler
|
@EventHandler
|
||||||
public void onSprint(PlayerToggleSprintEvent e) {
|
public void onSprint(PlayerToggleSprintEvent e) {
|
||||||
if (e.isSprinting()) {
|
if (e.isSprinting()) {
|
||||||
Talisman.checkFor(e, SlimefunItems.TALISMAN_TRAVELLER);
|
Talisman.trigger(e, SlimefunItems.TALISMAN_TRAVELLER);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -235,17 +235,23 @@ public class TalismanListener implements Listener {
|
|||||||
Map<Enchantment, Integer> enchantments = e.getEnchantsToAdd();
|
Map<Enchantment, Integer> enchantments = e.getEnchantsToAdd();
|
||||||
|
|
||||||
// Magician Talisman
|
// Magician Talisman
|
||||||
if (Talisman.checkFor(e, SlimefunItems.TALISMAN_MAGICIAN)) {
|
|
||||||
MagicianTalisman talisman = (MagicianTalisman) SlimefunItems.TALISMAN_MAGICIAN.getItem();
|
MagicianTalisman talisman = (MagicianTalisman) SlimefunItems.TALISMAN_MAGICIAN.getItem();
|
||||||
TalismanEnchantment enchantment = talisman.getRandomEnchantment(e.getItem(), enchantments.keySet());
|
TalismanEnchantment enchantment = talisman.getRandomEnchantment(e.getItem(), enchantments.keySet());
|
||||||
|
|
||||||
if (enchantment != null) {
|
if (enchantment != null && Talisman.trigger(e, SlimefunItems.TALISMAN_MAGICIAN)) {
|
||||||
|
/*
|
||||||
|
* Fix #2679
|
||||||
|
* By default, the Bukkit API doesn't allow us to give enchantment books extra enchantments.
|
||||||
|
*/
|
||||||
|
if (talisman.isEnchantmentBookAllowed() && e.getItem().getType() == Material.BOOK) {
|
||||||
|
e.getItem().addUnsafeEnchantment(enchantment.getEnchantment(), enchantment.getLevel());
|
||||||
|
} else {
|
||||||
enchantments.put(enchantment.getEnchantment(), enchantment.getLevel());
|
enchantments.put(enchantment.getEnchantment(), enchantment.getLevel());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wizard Talisman
|
// Wizard Talisman
|
||||||
if (!enchantments.containsKey(Enchantment.SILK_TOUCH) && Enchantment.LOOT_BONUS_BLOCKS.canEnchantItem(e.getItem()) && Talisman.checkFor(e, SlimefunItems.TALISMAN_WIZARD)) {
|
if (!enchantments.containsKey(Enchantment.SILK_TOUCH) && Enchantment.LOOT_BONUS_BLOCKS.canEnchantItem(e.getItem()) && Talisman.trigger(e, SlimefunItems.TALISMAN_WIZARD)) {
|
||||||
// Randomly lower some enchantments
|
// Randomly lower some enchantments
|
||||||
for (Map.Entry<Enchantment, Integer> entry : enchantments.entrySet()) {
|
for (Map.Entry<Enchantment, Integer> entry : enchantments.entrySet()) {
|
||||||
if (entry.getValue() > 1 && random.nextInt(100) < 40) {
|
if (entry.getValue() > 1 && random.nextInt(100) < 40) {
|
||||||
@ -260,7 +266,8 @@ public class TalismanListener implements Listener {
|
|||||||
|
|
||||||
@EventHandler(ignoreCancelled = true)
|
@EventHandler(ignoreCancelled = true)
|
||||||
public void onExperienceReceive(PlayerExpChangeEvent e) {
|
public void onExperienceReceive(PlayerExpChangeEvent e) {
|
||||||
if (e.getAmount() > 0 && Talisman.checkFor(e, SlimefunItems.TALISMAN_WISE)) {
|
// Check if the experience change was positive.
|
||||||
|
if (e.getAmount() > 0 && Talisman.trigger(e, SlimefunItems.TALISMAN_WISE)) {
|
||||||
// Double-XP
|
// Double-XP
|
||||||
e.setAmount(e.getAmount() * 2);
|
e.setAmount(e.getAmount() * 2);
|
||||||
}
|
}
|
||||||
@ -268,21 +275,27 @@ public class TalismanListener implements Listener {
|
|||||||
|
|
||||||
@EventHandler(ignoreCancelled = true)
|
@EventHandler(ignoreCancelled = true)
|
||||||
public void onBlockDropItems(BlockDropItemEvent e) {
|
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();
|
ItemStack item = e.getPlayer().getInventory().getItemInMainHand();
|
||||||
|
|
||||||
|
// We are going to ignore Silk Touch here
|
||||||
if (item.getType() != Material.AIR && item.getAmount() > 0 && !item.containsEnchantment(Enchantment.SILK_TOUCH)) {
|
if (item.getType() != Material.AIR && item.getAmount() > 0 && !item.containsEnchantment(Enchantment.SILK_TOUCH)) {
|
||||||
|
Material type = e.getBlockState().getType();
|
||||||
|
|
||||||
|
// We only want to double ores
|
||||||
|
if (SlimefunTag.MINER_TALISMAN_TRIGGERS.isTagged(type)) {
|
||||||
Collection<Item> drops = e.getItems();
|
Collection<Item> drops = e.getItems();
|
||||||
|
|
||||||
if (Talisman.checkFor(e, SlimefunItems.TALISMAN_MINER)) {
|
if (Talisman.trigger(e, SlimefunItems.TALISMAN_MINER, false)) {
|
||||||
int dropAmount = getAmountWithFortune(type, item.getEnchantmentLevel(Enchantment.LOOT_BONUS_BLOCKS));
|
int dropAmount = getAmountWithFortune(type, item.getEnchantmentLevel(Enchantment.LOOT_BONUS_BLOCKS));
|
||||||
|
|
||||||
|
// Keep track of whether we actually doubled the drops or not
|
||||||
boolean doubledDrops = false;
|
boolean doubledDrops = false;
|
||||||
|
|
||||||
|
// Loop through all dropped items
|
||||||
for (Item drop : drops) {
|
for (Item drop : drops) {
|
||||||
ItemStack droppedItem = drop.getItemStack();
|
ItemStack droppedItem = drop.getItemStack();
|
||||||
|
|
||||||
|
// We do not want to dupe blocks
|
||||||
if (!droppedItem.getType().isBlock()) {
|
if (!droppedItem.getType().isBlock()) {
|
||||||
int amount = Math.max(1, (dropAmount * 2) - droppedItem.getAmount());
|
int amount = Math.max(1, (dropAmount * 2) - droppedItem.getAmount());
|
||||||
e.getBlock().getWorld().dropItemNaturally(e.getBlock().getLocation(), new CustomItem(droppedItem, amount));
|
e.getBlock().getWorld().dropItemNaturally(e.getBlock().getLocation(), new CustomItem(droppedItem, amount));
|
||||||
@ -290,8 +303,14 @@ public class TalismanListener implements Listener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fixes #2077
|
||||||
if (doubledDrops) {
|
if (doubledDrops) {
|
||||||
SlimefunPlugin.getLocalization().sendMessage(e.getPlayer(), "messages.talisman.miner", true);
|
Talisman talisman = SlimefunItems.TALISMAN_MINER.getItem(Talisman.class);
|
||||||
|
|
||||||
|
// Fixes #2818
|
||||||
|
if (talisman != null) {
|
||||||
|
talisman.sendMessage(e.getPlayer());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -301,7 +320,7 @@ public class TalismanListener implements Listener {
|
|||||||
@EventHandler
|
@EventHandler
|
||||||
public void onBlockBreak(BlockBreakEvent e) {
|
public void onBlockBreak(BlockBreakEvent e) {
|
||||||
if (SlimefunTag.CAVEMAN_TALISMAN_TRIGGERS.isTagged(e.getBlock().getType())) {
|
if (SlimefunTag.CAVEMAN_TALISMAN_TRIGGERS.isTagged(e.getBlock().getType())) {
|
||||||
Talisman.checkFor(e, SlimefunItems.TALISMAN_CAVEMAN);
|
Talisman.trigger(e, SlimefunItems.TALISMAN_CAVEMAN);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,7 +13,6 @@ import org.bukkit.potion.PotionEffect;
|
|||||||
|
|
||||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||||
import io.github.thebusybiscuit.slimefun4.implementation.items.weapons.VampireBlade;
|
import io.github.thebusybiscuit.slimefun4.implementation.items.weapons.VampireBlade;
|
||||||
import me.mrCookieSlime.Slimefun.api.Slimefun;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This {@link Listener} is exclusively used for the {@link VampireBlade}.
|
* This {@link Listener} is exclusively used for the {@link VampireBlade}.
|
||||||
@ -44,7 +43,7 @@ public class VampireBladeListener implements Listener {
|
|||||||
Player p = (Player) e.getDamager();
|
Player p = (Player) e.getDamager();
|
||||||
|
|
||||||
if (blade.isItem(p.getInventory().getItemInMainHand())) {
|
if (blade.isItem(p.getInventory().getItemInMainHand())) {
|
||||||
if (Slimefun.hasUnlocked(p, blade, true)) {
|
if (blade.canUse(p, true)) {
|
||||||
blade.heal(p);
|
blade.heal(p);
|
||||||
} else {
|
} else {
|
||||||
e.setCancelled(true);
|
e.setCancelled(true);
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user