mirror of
https://github.com/StarWishsama/Slimefun4.git
synced 2024-09-19 19:25:48 +00:00
Merge branch 'master' into api/slimefun-item-get-optional-by
This commit is contained in:
commit
6a34470b47
1
.github/ISSUE_TEMPLATE/bug-report.yaml
vendored
1
.github/ISSUE_TEMPLATE/bug-report.yaml
vendored
@ -113,6 +113,7 @@ body:
|
||||
label: '🎮 Minecraft Version'
|
||||
description: 'Please select the Minecraft version of the server'
|
||||
options:
|
||||
- 1.20.x
|
||||
- 1.19.x
|
||||
- 1.18.x
|
||||
- 1.17.x
|
||||
|
2
.github/PULL_REQUEST_TEMPLATE.md
vendored
2
.github/PULL_REQUEST_TEMPLATE.md
vendored
@ -17,7 +17,7 @@
|
||||
<!-- Don't worry, these are not requirements. They only serve as guidance. -->
|
||||
- [ ] I have fully tested the proposed changes and promise that they will not break everything into chaos.
|
||||
- [ ] I have also tested the proposed changes in combination with various popular addons and can confirm my changes do not break them.
|
||||
- [ ] I have made sure that the proposed changes do not break compatibility across the supported Minecraft versions (1.16.* - 1.19.*).
|
||||
- [ ] I have made sure that the proposed changes do not break compatibility across the supported Minecraft versions (1.16.* - 1.20.*).
|
||||
- [ ] I followed the existing code standards and didn't mess up the formatting.
|
||||
- [ ] I did my best to add documentation to any public classes or methods I added.
|
||||
- [ ] I have added `Nonnull` and `Nullable` annotations to my methods to indicate their behaviour for null values
|
||||
|
2
.github/workflows/auto-approve.yml
vendored
2
.github/workflows/auto-approve.yml
vendored
@ -20,7 +20,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Approve via actions
|
||||
uses: hmarr/auto-approve-action@v3.2.0
|
||||
uses: hmarr/auto-approve-action@v3.2.1
|
||||
if: github.actor == 'TheBusyBot' || github.actor == 'renovate[bot]'
|
||||
with:
|
||||
github-token: "${{ secrets.GITHUB_TOKEN }}"
|
||||
|
4
.github/workflows/auto-squash.yml
vendored
4
.github/workflows/auto-squash.yml
vendored
@ -22,7 +22,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Auto squash
|
||||
uses: pascalgn/automerge-action@v0.15.5
|
||||
uses: pascalgn/automerge-action@v0.15.6
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.ACCESS_TOKEN }}
|
||||
UPDATE_RETRIES: 0
|
||||
@ -42,7 +42,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Auto squash
|
||||
uses: pascalgn/automerge-action@v0.15.5
|
||||
uses: pascalgn/automerge-action@v0.15.6
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.ACCESS_TOKEN }}
|
||||
UPDATE_RETRIES: 0
|
||||
|
4
.github/workflows/discord-webhook.yml
vendored
4
.github/workflows/discord-webhook.yml
vendored
@ -21,10 +21,10 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3.3.0
|
||||
uses: actions/checkout@v3.5.3
|
||||
|
||||
- name: Set up Java JDK 17
|
||||
uses: actions/setup-java@v3.10.0
|
||||
uses: actions/setup-java@v3.12.0
|
||||
with:
|
||||
distribution: 'adopt'
|
||||
java-version: '17'
|
||||
|
2
.github/workflows/maven-compiler.yml
vendored
2
.github/workflows/maven-compiler.yml
vendored
@ -28,7 +28,7 @@ jobs:
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Set up JDK 17
|
||||
uses: actions/setup-java@v3.10.0
|
||||
uses: actions/setup-java@v3.12.0
|
||||
with:
|
||||
distribution: 'adopt'
|
||||
java-version: '17'
|
||||
|
2
.github/workflows/merge-conflicts.yml
vendored
2
.github/workflows/merge-conflicts.yml
vendored
@ -11,7 +11,7 @@ permissions:
|
||||
|
||||
jobs:
|
||||
validate:
|
||||
|
||||
if: github.repository == 'Slimefun/Slimefun4'
|
||||
name: Check for merge conflicts
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
|
6
.github/workflows/pr-labels.yml
vendored
6
.github/workflows/pr-labels.yml
vendored
@ -1,7 +1,7 @@
|
||||
name: Pull Request Labels
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
pull_request_target:
|
||||
types:
|
||||
- opened
|
||||
|
||||
@ -31,7 +31,7 @@ jobs:
|
||||
api: '🔧 API'
|
||||
compatibility: '🤝 Compatibility'
|
||||
|
||||
- uses: thollander/actions-comment-pull-request@v2.3.1
|
||||
- uses: thollander/actions-comment-pull-request@v2.4.2
|
||||
name: Leave a comment about the applied label
|
||||
if: ${{ steps.labeller.outputs.applied != 0 }}
|
||||
with:
|
||||
@ -40,7 +40,7 @@ jobs:
|
||||
Your Pull Request was automatically labelled as: "${{ steps.labeller.outputs.applied }}"
|
||||
Thank you for contributing to this project! ❤️
|
||||
|
||||
- uses: thollander/actions-comment-pull-request@v2.3.1
|
||||
- uses: thollander/actions-comment-pull-request@v2.4.2
|
||||
name: Leave a comment about our branch naming convention
|
||||
if: ${{ steps.labeller.outputs.applied == 0 }}
|
||||
with:
|
||||
|
82
.github/workflows/preview-builds.yml
vendored
Normal file
82
.github/workflows/preview-builds.yml
vendored
Normal file
@ -0,0 +1,82 @@
|
||||
name: Preview builds
|
||||
|
||||
on:
|
||||
workflow_run:
|
||||
workflows: ["Pull Request"]
|
||||
types:
|
||||
- completed
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
preview:
|
||||
if: ${{ github.repository_owner == 'Slimefun' && github.event.workflow_run.conclusion == 'success' }}
|
||||
name: Build and Publish the jar
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
# Kinda jank way to grab the PR and commit hash and then download the artifact
|
||||
# TODO: Move this code to our own mini-action
|
||||
- name: Grab PR & run ID and download the artifact
|
||||
uses: actions/github-script@v6
|
||||
with:
|
||||
script: |
|
||||
const allArtifacts = await github.rest.actions.listWorkflowRunArtifacts({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
run_id: context.payload.workflow_run.id,
|
||||
});
|
||||
|
||||
for (const artifact of allArtifacts.data.artifacts) {
|
||||
// Extract the PR number and commit hash from the artifact name
|
||||
const match = /^slimefun-(\d+)-([a-f0-9]{8})$/.exec(artifact.name);
|
||||
if (match) {
|
||||
require("fs").appendFileSync(
|
||||
process.env.GITHUB_ENV,
|
||||
`\nPR_NUMBER=${match[1]}` +
|
||||
`\nCOMMIT_HASH=${match[2]}`
|
||||
);
|
||||
|
||||
const download = await github.rest.actions.downloadArtifact({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
artifact_id: artifact.id,
|
||||
archive_format: 'zip',
|
||||
});
|
||||
require('fs').writeFileSync(`${process.env.GITHUB_WORKSPACE}/preview.zip`, Buffer.from(download.data))
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
# Unzip the artifact
|
||||
- name: Unzip
|
||||
run: |
|
||||
unzip preview.zip
|
||||
rm preview.zip
|
||||
mv 'Slimefun vPreview Build #${{ env.PR_NUMBER }}-${{ env.COMMIT_HASH }}.jar' preview.jar
|
||||
|
||||
- name: Upload to preview service
|
||||
run: |
|
||||
curl -X POST \
|
||||
-H 'Authorization: ${{ secrets.PUBLISH_TOKEN }}' \
|
||||
-H "X-Checksum: $(sha256sum 'preview.jar' | awk '{print $1}')" \
|
||||
--data-binary '@preview.jar' \
|
||||
https://preview-builds.walshy.dev/upload/Slimefun/${{ env.PR_NUMBER }}/${{ env.COMMIT_HASH }}
|
||||
|
||||
- name: Post comment
|
||||
uses: marocchino/sticky-pull-request-comment@v2
|
||||
with:
|
||||
number: ${{ env.PR_NUMBER }}
|
||||
message: |
|
||||
### Slimefun preview build
|
||||
|
||||
A Slimefun preview build is available for testing!
|
||||
Commit: ${{ env.COMMIT_HASH }}
|
||||
|
||||
https://preview-builds.walshy.dev/download/Slimefun/${{ env.PR_NUMBER }}/${{ env.COMMIT_HASH }}
|
||||
|
||||
> **Note**: This is not a supported build and is only here for the purposes of testing.
|
||||
> Do not run this on a live server and do not report bugs anywhere but this PR!
|
52
.github/workflows/pull-request.yml
vendored
Normal file
52
.github/workflows/pull-request.yml
vendored
Normal file
@ -0,0 +1,52 @@
|
||||
name: Pull Request
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- '.github/workflows/**'
|
||||
- 'src/**'
|
||||
- 'pom.xml'
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
setup-preview-build:
|
||||
name: Preview build
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Set up JDK 17
|
||||
uses: actions/setup-java@v3.12.0
|
||||
with:
|
||||
distribution: 'adopt'
|
||||
java-version: '17'
|
||||
java-package: jdk
|
||||
architecture: x64
|
||||
|
||||
- name: Cache Maven packages
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/.m2
|
||||
key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
|
||||
restore-keys: ${{ runner.os }}-m2
|
||||
|
||||
# Setup for the preview build
|
||||
- run: |
|
||||
SHORT_COMMIT_HASH=$(git rev-parse --short=8 ${{ github.sha }})
|
||||
JAR_VERSION="Preview Build #${{ github.event.number }}-$SHORT_COMMIT_HASH"
|
||||
echo "SHORT_COMMIT_HASH=$SHORT_COMMIT_HASH" >> "$GITHUB_ENV"
|
||||
echo "JAR_VERSION=$JAR_VERSION" >> "$GITHUB_ENV"
|
||||
sed -i "s/<version>4.9-UNOFFICIAL<\/version>/<version>$JAR_VERSION<\/version>/g" pom.xml
|
||||
|
||||
- name: Build with Maven
|
||||
run: mvn package
|
||||
|
||||
- name: Upload the artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: slimefun-${{ github.event.number }}-${{ env.SHORT_COMMIT_HASH }}
|
||||
path: 'target/Slimefun v${{ env.JAR_VERSION }}.jar'
|
4
.github/workflows/sonarcloud.yml
vendored
4
.github/workflows/sonarcloud.yml
vendored
@ -19,12 +19,12 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3.3.0
|
||||
uses: actions/checkout@v3.5.3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set up JDK 17
|
||||
uses: actions/setup-java@v3.10.0
|
||||
uses: actions/setup-java@v3.12.0
|
||||
with:
|
||||
distribution: 'adopt'
|
||||
java-version: '17'
|
||||
|
41
CHANGELOG.md
41
CHANGELOG.md
@ -1,5 +1,7 @@
|
||||
# Table of contents
|
||||
- [Release Candidate 34 (TBD)](#release-candidate-34-tbd)
|
||||
- [Release Candidate 36 (TBD)](#release-candidate-36-tbd)
|
||||
- [Release Candidate 35 (7 Jul 2023)](#release-candidate-35-7-jul-2023)
|
||||
- [Release Candidate 34 (20 Jun 2023)](#release-candidate-34-20-jun-2023)
|
||||
- [Release Candidate 33 (07 Jan 2023)](#release-candidate-33-07-jan-2023)
|
||||
- [Release Candidate 32 (26 Jun 2022)](#release-candidate-32-26-jun-2022)
|
||||
- [Release Candidate 31 (14 Mar 2022)](#release-candidate-31-14-mar-2022)
|
||||
@ -34,8 +36,33 @@
|
||||
- [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 36 (TBD)
|
||||
|
||||
## Release Candidate 34 (TBD)
|
||||
#### Additions
|
||||
|
||||
#### Changes
|
||||
|
||||
#### Fixes
|
||||
|
||||
## Release Candidate 35 (7 Jul 2023)
|
||||
|
||||
#### Additions
|
||||
* Added `sounds.yml` file to configure sound effects for Slimefun
|
||||
* Added preview builds to the repo, PRs will now have a build which testers can use
|
||||
* (API) Added SlimefunBlockBreakEvent and SlimefunBlockPlaceEvent events for plugins/addons to implement
|
||||
* (API) Added an efficient way to clear BlockStorage within a chunk - BlockStorage.clearAllBlockInfoAtChunk
|
||||
* (API) Added DistinctiveItem, a way to distinguish your item with more than just ID
|
||||
* (API) Added ExternallyInteractable, a way for addons to define "interactions" for blocks
|
||||
|
||||
#### Changes
|
||||
* Moved all sound effects to the new sound system
|
||||
|
||||
#### Fixes
|
||||
* Fixed recipe shift in multiblocks when items are disabled (#3286)
|
||||
* Fixed backpack dupe within cargo (#3379)
|
||||
|
||||
## Release Candidate 34 (20 Jun 2023)
|
||||
https://thebusybiscuit.github.io/builds/TheBusyBiscuit/Slimefun4/stable/#34
|
||||
|
||||
#### Additions
|
||||
* Added "Cobbled Deepslate -> Gravel" recipe to the Grind Stone
|
||||
@ -45,6 +72,8 @@
|
||||
* (API) Added EnergyNet#getConsumers()
|
||||
* Added Bamboo as a fuel type for Tier 1 Androids
|
||||
* Added "Basalt -> Blackstone" recipe to the Grind Stone
|
||||
* Added a way to automate salt with the Ore Washer
|
||||
* Added compatibility for Minecraft 1.20
|
||||
|
||||
#### Changes
|
||||
* Removed 1.14.* and 1.15.* support
|
||||
@ -56,6 +85,7 @@
|
||||
* Tuff
|
||||
* Clay
|
||||
* Skulk
|
||||
* Lumber Axe no longer works when shifting
|
||||
|
||||
#### Fixes
|
||||
* Fixed #3741
|
||||
@ -64,6 +94,13 @@
|
||||
* Fixed #3758
|
||||
* Fixed #3701
|
||||
* Fixed #3361
|
||||
* Fixed #3254
|
||||
* Fixed #3443
|
||||
* Fixed #3511
|
||||
* Fixed #3524
|
||||
* Fixed #3657
|
||||
* Fixed #3768
|
||||
* Fixed #3414
|
||||
|
||||
## Release Candidate 33 (07 Jan 2023)
|
||||
https://thebusybiscuit.github.io/builds/TheBusyBiscuit/Slimefun4/stable/#33
|
||||
|
@ -30,7 +30,7 @@ Here is a full summary of the differences between the two different versions of
|
||||
|
||||
| | development (latest) | "stable" |
|
||||
| ------------------ | -------- | -------- |
|
||||
| **Minecraft version(s)** | :video_game: **1.16.\* - 1.19.\*** | :video_game: **1.14.\* - 1.19.\*** |
|
||||
| **Minecraft version(s)** | :video_game: **1.16.\* - 1.20.\*** | :video_game: **1.16.\* - 1.20.\*** |
|
||||
| **Java version** | :computer: **Java 16 (or higher)** | :computer: **Java 16 (or higher)** |
|
||||
| **automatic updates** | :heavy_check_mark: | :heavy_check_mark: |
|
||||
| **frequent updates** | :heavy_check_mark: | :x: |
|
||||
|
41
pom.xml
41
pom.xml
@ -26,7 +26,7 @@
|
||||
<maven.compiler.target>16</maven.compiler.target>
|
||||
|
||||
<!-- Spigot properties -->
|
||||
<spigot.version>1.19</spigot.version>
|
||||
<spigot.version>1.20</spigot.version>
|
||||
<spigot.javadocs>https://hub.spigotmc.org/javadocs/spigot/</spigot.javadocs>
|
||||
|
||||
<!-- Default settings for sonarcloud.io -->
|
||||
@ -63,7 +63,7 @@
|
||||
<repository>
|
||||
<!-- PaperLib -->
|
||||
<id>paper-repo</id>
|
||||
<url>https://papermc.io/repo/repository/maven-public</url>
|
||||
<url>https://repo.papermc.io/repository/maven-public/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<!-- ItemsAdder -->
|
||||
@ -130,7 +130,7 @@
|
||||
<!-- Attach sources -->
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-source-plugin</artifactId>
|
||||
<version>3.2.1</version>
|
||||
<version>3.3.0</version>
|
||||
|
||||
<executions>
|
||||
<execution>
|
||||
@ -146,7 +146,7 @@
|
||||
<!-- Plugin for Unit Tests -->
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>3.0.0-M9</version>
|
||||
<version>3.1.2</version>
|
||||
|
||||
<configuration>
|
||||
<junitArtifactName>org.junit.jupiter:junit-jupiter</junitArtifactName>
|
||||
@ -165,7 +165,7 @@
|
||||
<!-- Code Coverage Reports -->
|
||||
<groupId>org.jacoco</groupId>
|
||||
<artifactId>jacoco-maven-plugin</artifactId>
|
||||
<version>0.8.8</version>
|
||||
<version>0.8.10</version>
|
||||
|
||||
<executions>
|
||||
<execution>
|
||||
@ -191,7 +191,7 @@
|
||||
<!-- Dependency shading -->
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.4.1</version>
|
||||
<version>3.5.0</version>
|
||||
|
||||
<configuration>
|
||||
<!-- Relocate these to avoid clashes and conflicts -->
|
||||
@ -351,10 +351,11 @@
|
||||
</dependency>
|
||||
|
||||
<!-- Shaded packages -->
|
||||
<!-- TODO: Revert changes back to maven when dough 1.3 released -->
|
||||
<dependency>
|
||||
<groupId>io.github.baked-libs</groupId>
|
||||
<groupId>com.github.baked-libs.dough</groupId>
|
||||
<artifactId>dough-api</artifactId>
|
||||
<version>1.2.0</version>
|
||||
<version>d3b0997226</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -366,7 +367,7 @@
|
||||
<dependency>
|
||||
<groupId>com.konghq</groupId>
|
||||
<artifactId>unirest-java</artifactId>
|
||||
<version>3.14.1</version>
|
||||
<version>3.14.5</version>
|
||||
<scope>compile</scope>
|
||||
|
||||
<exclusions>
|
||||
@ -382,13 +383,19 @@
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter</artifactId>
|
||||
<version>5.9.2</version>
|
||||
<version>5.10.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<version>5.2.0</version>
|
||||
<version>5.4.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-simple</artifactId>
|
||||
<version>2.0.7</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -411,7 +418,7 @@
|
||||
<dependency>
|
||||
<groupId>com.sk89q.worldedit</groupId>
|
||||
<artifactId>worldedit-core</artifactId>
|
||||
<version>7.2.13</version>
|
||||
<version>7.2.15</version>
|
||||
<scope>provided</scope>
|
||||
|
||||
<exclusions>
|
||||
@ -425,7 +432,7 @@
|
||||
<dependency>
|
||||
<groupId>com.sk89q.worldedit</groupId>
|
||||
<artifactId>worldedit-bukkit</artifactId>
|
||||
<version>7.2.13</version>
|
||||
<version>7.2.15</version>
|
||||
<scope>provided</scope>
|
||||
|
||||
<exclusions>
|
||||
@ -439,7 +446,7 @@
|
||||
<dependency>
|
||||
<groupId>com.gmail.nossr50.mcMMO</groupId>
|
||||
<artifactId>mcMMO</artifactId>
|
||||
<version>2.1.218</version>
|
||||
<version>2.1.222</version>
|
||||
<scope>provided</scope>
|
||||
|
||||
<exclusions>
|
||||
@ -453,7 +460,7 @@
|
||||
<dependency>
|
||||
<groupId>me.clip</groupId>
|
||||
<artifactId>placeholderapi</artifactId>
|
||||
<version>2.11.2</version>
|
||||
<version>2.11.3</version>
|
||||
<scope>provided</scope>
|
||||
|
||||
<exclusions>
|
||||
@ -481,7 +488,7 @@
|
||||
<dependency>
|
||||
<groupId>com.github.LoneDev6</groupId>
|
||||
<artifactId>itemsadder-api</artifactId>
|
||||
<version>3.2.5</version>
|
||||
<version>3.5.0b</version>
|
||||
<scope>provided</scope>
|
||||
|
||||
<exclusions>
|
||||
@ -495,7 +502,7 @@
|
||||
<dependency>
|
||||
<groupId>net.imprex</groupId>
|
||||
<artifactId>orebfuscator-api</artifactId>
|
||||
<version>5.3.0</version>
|
||||
<version>5.3.3</version>
|
||||
<scope>provided</scope>
|
||||
|
||||
<exclusions>
|
||||
|
@ -43,6 +43,12 @@ public enum MinecraftVersion {
|
||||
*/
|
||||
MINECRAFT_1_19(19, "1.19.x"),
|
||||
|
||||
/**
|
||||
* This constant represents Minecraft (Java Edition) Version 1.20
|
||||
* ("The Trails & Tales Update")
|
||||
*/
|
||||
MINECRAFT_1_20(20, "1.20.x"),
|
||||
|
||||
/**
|
||||
* This constant represents an exceptional state in which we were unable
|
||||
* to identify the Minecraft Version we are using
|
||||
|
@ -0,0 +1,106 @@
|
||||
package io.github.thebusybiscuit.slimefun4.api.events;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
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.block.BlockEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem;
|
||||
|
||||
/**
|
||||
* This {@link Event} is fired whenever a {@link SlimefunItem} placed as a {@link Block} in the world is broken.
|
||||
*
|
||||
* @author J3fftw1
|
||||
*/
|
||||
public class SlimefunBlockBreakEvent extends Event implements Cancellable {
|
||||
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
|
||||
private final Block blockBroken;
|
||||
private final SlimefunItem slimefunItem;
|
||||
private final ItemStack heldItem;
|
||||
private final Player player;
|
||||
|
||||
private boolean cancelled = false;
|
||||
|
||||
/**
|
||||
* @param player
|
||||
* The {@link Player} who broke this {@link SlimefunItem}
|
||||
* @param heldItem
|
||||
* The {@link ItemStack} held by the {@link Player}
|
||||
* @param blockBroken
|
||||
* The {@link Block} broken by the {@link Player}
|
||||
* @param slimefunItem
|
||||
* The {@link SlimefunItem} within the {@link ItemStack}
|
||||
*/
|
||||
@ParametersAreNonnullByDefault
|
||||
public SlimefunBlockBreakEvent(Player player, ItemStack heldItem, Block blockBroken, SlimefunItem slimefunItem) {
|
||||
super();
|
||||
|
||||
this.player = player;
|
||||
this.heldItem = heldItem;
|
||||
this.blockBroken = blockBroken;
|
||||
this.slimefunItem = slimefunItem;
|
||||
}
|
||||
|
||||
/**
|
||||
* This gets the broken {@link Block}
|
||||
*
|
||||
* @return The broken {@link Block}
|
||||
*/
|
||||
public @Nonnull Block getBlockBroken() {
|
||||
return blockBroken;
|
||||
}
|
||||
|
||||
/**
|
||||
* This gets the {@link SlimefunItem} being broken
|
||||
*
|
||||
* @return The {@link SlimefunItem} being broken
|
||||
*/
|
||||
public @Nonnull SlimefunItem getSlimefunItem() {
|
||||
return slimefunItem;
|
||||
}
|
||||
|
||||
/**
|
||||
* The {@link ItemStack} held by the {@link Player}
|
||||
*
|
||||
* @return The held {@link ItemStack}
|
||||
*/
|
||||
public @Nonnull ItemStack getHeldItem() {
|
||||
return heldItem;
|
||||
}
|
||||
|
||||
/**
|
||||
* This gets the {@link Player}
|
||||
*
|
||||
* @return The {@link Player}
|
||||
*/
|
||||
public @Nonnull Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return cancelled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCancelled(boolean cancelled) {
|
||||
this.cancelled = cancelled;
|
||||
}
|
||||
|
||||
public static @Nonnull HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nonnull HandlerList getHandlers() {
|
||||
return getHandlerList();
|
||||
}
|
||||
}
|
@ -0,0 +1,105 @@
|
||||
package io.github.thebusybiscuit.slimefun4.api.events;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
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.inventory.ItemStack;
|
||||
|
||||
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem;
|
||||
|
||||
/**
|
||||
* This {@link Event} is fired whenever a {@link SlimefunItem} is placed as a {@link Block} in the world.
|
||||
*
|
||||
* @author J3fftw1
|
||||
*/
|
||||
public class SlimefunBlockPlaceEvent extends Event implements Cancellable {
|
||||
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
|
||||
private final Block blockPlaced;
|
||||
private final SlimefunItem slimefunItem;
|
||||
private final ItemStack placedItem;
|
||||
private final Player player;
|
||||
|
||||
private boolean cancelled = false;
|
||||
|
||||
/**
|
||||
* @param player
|
||||
* The {@link Player} who placed this {@link SlimefunItem}
|
||||
* @param placedItem
|
||||
* The {@link ItemStack} held by the {@link Player}
|
||||
* @param blockPlaced
|
||||
* The {@link Block} placed by the {@link Player}
|
||||
* @param slimefunItem
|
||||
* The {@link SlimefunItem} within the {@link ItemStack}
|
||||
*/
|
||||
@ParametersAreNonnullByDefault
|
||||
public SlimefunBlockPlaceEvent(Player player, ItemStack placedItem, Block blockPlaced, SlimefunItem slimefunItem) {
|
||||
super();
|
||||
|
||||
this.player = player;
|
||||
this.placedItem = placedItem;
|
||||
this.blockPlaced = blockPlaced;
|
||||
this.slimefunItem = slimefunItem;
|
||||
}
|
||||
|
||||
/**
|
||||
* This gets the placed {@link Block}
|
||||
*
|
||||
* @return The placed {@link Block}
|
||||
*/
|
||||
public @Nonnull Block getBlockPlaced() {
|
||||
return blockPlaced;
|
||||
}
|
||||
|
||||
/**
|
||||
* This gets the {@link SlimefunItem} being placed
|
||||
*
|
||||
* @return The {@link SlimefunItem} being placed
|
||||
*/
|
||||
public @Nonnull SlimefunItem getSlimefunItem() {
|
||||
return slimefunItem;
|
||||
}
|
||||
|
||||
/**
|
||||
* This gets the placed {@link ItemStack}.
|
||||
*
|
||||
* @return The placed {@link ItemStack}
|
||||
*/
|
||||
public @Nonnull ItemStack getItemStack() {
|
||||
return placedItem;
|
||||
}
|
||||
|
||||
/**
|
||||
* This gets the {@link Player}
|
||||
*
|
||||
* @return The {@link Player}
|
||||
*/
|
||||
public @Nonnull Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return cancelled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCancelled(boolean cancelled) {
|
||||
this.cancelled = cancelled;
|
||||
}
|
||||
|
||||
public static @Nonnull HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nonnull HandlerList getHandlers() {
|
||||
return getHandlerList();
|
||||
}
|
||||
}
|
@ -15,7 +15,6 @@ import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.World.Environment;
|
||||
import org.bukkit.entity.Player;
|
||||
@ -29,6 +28,7 @@ import io.github.thebusybiscuit.slimefun4.api.geo.GEOResource;
|
||||
import io.github.thebusybiscuit.slimefun4.api.geo.ResourceManager;
|
||||
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem;
|
||||
import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile;
|
||||
import io.github.thebusybiscuit.slimefun4.core.services.sounds.SoundEffect;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.items.gps.GPSTransmitter;
|
||||
@ -257,7 +257,7 @@ public class GPSNetwork {
|
||||
menu.addItem(slot, new CustomItemStack(waypoint.getIcon(), waypoint.getName().replace("player:death ", ""), "&8\u21E8 &7World: &f" + l.getWorld().getName(), "&8\u21E8 &7X: &f" + l.getX(), "&8\u21E8 &7Y: &f" + l.getY(), "&8\u21E8 &7Z: &f" + l.getZ(), "", "&8\u21E8 &cClick to delete"));
|
||||
menu.addMenuClickHandler(slot, (pl, s, item, action) -> {
|
||||
profile.removeWaypoint(waypoint);
|
||||
pl.playSound(pl.getLocation(), Sound.UI_BUTTON_CLICK, 1F, 1F);
|
||||
SoundEffect.GPS_NETWORK_OPEN_PANEL_SOUND.playFor(p);
|
||||
|
||||
openWaypointControlPanel(pl);
|
||||
return false;
|
||||
@ -290,7 +290,7 @@ public class GPSNetwork {
|
||||
}
|
||||
|
||||
Slimefun.getLocalization().sendMessage(p, "gps.waypoint.new", true);
|
||||
p.playSound(p.getLocation(), Sound.BLOCK_NOTE_BLOCK_PLING, 0.5F, 1F);
|
||||
SoundEffect.GPS_NETWORK_CREATE_WAYPOINT.playFor(p);
|
||||
|
||||
ChatInput.waitForPlayer(Slimefun.instance(), p, message -> addWaypoint(p, message, l));
|
||||
});
|
||||
@ -333,7 +333,7 @@ public class GPSNetwork {
|
||||
|
||||
profile.addWaypoint(new Waypoint(profile, id, event.getLocation(), event.getName()));
|
||||
|
||||
p.playSound(p.getLocation(), Sound.BLOCK_NOTE_BLOCK_PLING, 1F, 1F);
|
||||
SoundEffect.GPS_NETWORK_ADD_WAYPOINT.playFor(p);
|
||||
Slimefun.getLocalization().sendMessage(p, "gps.waypoint.added", true);
|
||||
}
|
||||
});
|
||||
|
@ -13,7 +13,6 @@ import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Particle;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
@ -22,6 +21,7 @@ import org.bukkit.potion.PotionEffectType;
|
||||
import io.github.bakedlibs.dough.common.ChatColors;
|
||||
import io.github.bakedlibs.dough.items.CustomItemStack;
|
||||
import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile;
|
||||
import io.github.thebusybiscuit.slimefun4.core.services.sounds.SoundEffect;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.items.teleporter.Teleporter;
|
||||
import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils;
|
||||
@ -70,8 +70,7 @@ public final class TeleportationManager {
|
||||
@ParametersAreNonnullByDefault
|
||||
public void openTeleporterGUI(Player p, UUID ownerUUID, Block b, int complexity) {
|
||||
if (teleporterUsers.add(p.getUniqueId())) {
|
||||
p.playSound(p.getLocation(), Sound.UI_BUTTON_CLICK, 1F, 1F);
|
||||
|
||||
SoundEffect.TELEPORTATION_MANAGER_OPEN_GUI.playFor(p);
|
||||
PlayerProfile.fromUUID(ownerUUID, profile -> {
|
||||
ChestMenu menu = new ChestMenu("&3Teleporter");
|
||||
menu.addMenuCloseHandler(pl -> teleporterUsers.remove(pl.getUniqueId()));
|
||||
@ -203,8 +202,7 @@ public final class TeleportationManager {
|
||||
p.sendTitle(ChatColors.color(Slimefun.getLocalization().getMessage(p, "machines.TELEPORTER.teleporting")), ChatColors.color("&b" + progress + "%"), 0, 60, 0);
|
||||
|
||||
source.getWorld().spawnParticle(Particle.PORTAL, source, progress * 2, 0.2F, 0.8F, 0.2F);
|
||||
source.getWorld().playSound(source, Sound.BLOCK_BEACON_AMBIENT, 1F, 0.6F);
|
||||
|
||||
SoundEffect.TELEPORT_UPDATE_SOUND.playFor(p);
|
||||
Slimefun.runSync(() -> updateProgress(uuid, speed, progress + speed, source, destination, resistance), 10L);
|
||||
}
|
||||
} else {
|
||||
@ -229,7 +227,7 @@ public final class TeleportationManager {
|
||||
// Spawn some particles for aesthetic reasons.
|
||||
Location loc = new Location(destination.getWorld(), destination.getX(), destination.getY() + 1, destination.getZ());
|
||||
destination.getWorld().spawnParticle(Particle.PORTAL, loc, 200, 0.2F, 0.8F, 0.2F);
|
||||
destination.getWorld().playSound(destination, Sound.BLOCK_BEACON_ACTIVATE, 1F, 1F);
|
||||
SoundEffect.TELEPORT_SOUND.playFor(p);
|
||||
teleporterUsers.remove(p.getUniqueId());
|
||||
} else {
|
||||
/*
|
||||
|
@ -12,7 +12,7 @@ import org.bukkit.inventory.meta.Damageable;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.items.armor.SlimefunArmorPiece;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.tasks.ArmorTask;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.tasks.armor.SlimefunArmorTask;
|
||||
|
||||
/**
|
||||
* This class serves as a way of checking whether a {@link Player} has changed their armor
|
||||
@ -25,7 +25,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.tasks.ArmorTask;
|
||||
* @author TheBusyBiscuit
|
||||
*
|
||||
* @see SlimefunArmorPiece
|
||||
* @see ArmorTask
|
||||
* @see SlimefunArmorTask
|
||||
*/
|
||||
public final class HashedArmorpiece {
|
||||
|
||||
|
@ -39,16 +39,12 @@ import io.github.thebusybiscuit.slimefun4.core.SlimefunRegistry;
|
||||
import io.github.thebusybiscuit.slimefun4.core.attributes.NotConfigurable;
|
||||
import io.github.thebusybiscuit.slimefun4.core.attributes.Placeable;
|
||||
import io.github.thebusybiscuit.slimefun4.core.attributes.Radioactive;
|
||||
import io.github.thebusybiscuit.slimefun4.core.attributes.Rechargeable;
|
||||
import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuide;
|
||||
import io.github.thebusybiscuit.slimefun4.core.handlers.GlobalItemHandler;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.items.VanillaItem;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.items.backpacks.SlimefunBackpack;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.enchanting.AutoDisenchanter;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.enchanting.AutoEnchanter;
|
||||
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
|
||||
import io.github.thebusybiscuit.slimefun4.utils.itemstack.ItemStackWrapper;
|
||||
|
||||
import me.mrCookieSlime.Slimefun.Objects.handlers.BlockTicker;
|
||||
|
||||
@ -479,6 +475,14 @@ public class SlimefunItem implements Placeable {
|
||||
// Now we can be certain this item should be enabled
|
||||
if (state == ItemState.ENABLED) {
|
||||
onEnable();
|
||||
} else {
|
||||
// Clear item handlers if we are disabled so that calling them isn't possible later on
|
||||
for (ItemHandler handler : this.itemhandlers.values()) {
|
||||
if (handler instanceof BlockTicker) {
|
||||
Slimefun.getRegistry().getTickerBlocks().remove(getId());
|
||||
}
|
||||
}
|
||||
this.itemhandlers.clear();
|
||||
}
|
||||
|
||||
// Lock the SlimefunItemStack from any accidental manipulations
|
||||
@ -767,14 +771,8 @@ public class SlimefunItem implements Placeable {
|
||||
}
|
||||
}
|
||||
|
||||
// Backwards compatibility
|
||||
if (Slimefun.getRegistry().isBackwardsCompatible()) {
|
||||
boolean loreInsensitive = this instanceof Rechargeable || this instanceof SlimefunBackpack || id.equals("BROKEN_SPAWNER") || id.equals("REINFORCED_SPAWNER");
|
||||
return SlimefunUtils.isItemSimilar(item, this.itemStackTemplate, !loreInsensitive);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is used for internal purposes only.
|
||||
@ -1190,33 +1188,8 @@ public class SlimefunItem implements Placeable {
|
||||
|
||||
Optional<String> itemID = Slimefun.getItemDataService().getItemData(item);
|
||||
|
||||
if (itemID.isPresent()) {
|
||||
return getById(itemID.get());
|
||||
}
|
||||
return itemID.map(SlimefunItem::getById).orElse(null);
|
||||
|
||||
// Backwards compatibility
|
||||
if (Slimefun.getRegistry().isBackwardsCompatible()) {
|
||||
// This wrapper improves the heavy ItemStack#getItemMeta() call by caching it.
|
||||
ItemStackWrapper wrapper = ItemStackWrapper.wrap(item);
|
||||
|
||||
/*
|
||||
* Quite expensive performance-wise.
|
||||
* But necessary for supporting legacy items
|
||||
*/
|
||||
for (SlimefunItem sfi : Slimefun.getRegistry().getAllSlimefunItems()) {
|
||||
if (sfi.isItem(wrapper)) {
|
||||
/*
|
||||
* If we have to loop all items for the given item, then at least
|
||||
* set the id via PersistentDataAPI for future performance boosts
|
||||
*/
|
||||
Slimefun.getItemDataService().setItemData(item, sfi.getId());
|
||||
|
||||
return sfi;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -17,6 +17,7 @@ import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile;
|
||||
import io.github.thebusybiscuit.slimefun4.core.guide.GuideHistory;
|
||||
import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuide;
|
||||
import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideMode;
|
||||
import io.github.thebusybiscuit.slimefun4.core.services.sounds.SoundEffect;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.guide.SurvivalSlimefunGuide;
|
||||
import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils;
|
||||
@ -86,7 +87,7 @@ public class NestedItemGroup extends FlexItemGroup {
|
||||
SurvivalSlimefunGuide guide = (SurvivalSlimefunGuide) Slimefun.getRegistry().getSlimefunGuide(mode);
|
||||
|
||||
menu.setEmptySlotsClickable(false);
|
||||
menu.addMenuOpeningHandler(pl -> pl.playSound(pl.getLocation(), guide.getSound(), 1, 1));
|
||||
menu.addMenuOpeningHandler(SoundEffect.GUIDE_BUTTON_CLICK_SOUND::playFor);
|
||||
guide.createHeader(p, profile, menu);
|
||||
|
||||
menu.addItem(1, new CustomItemStack(ChestMenuUtils.getBackButton(p, "", ChatColor.GRAY + Slimefun.getLocalization().getMessage(p, "guide.back.guide"))));
|
||||
|
@ -36,6 +36,7 @@ import io.github.bakedlibs.dough.config.Config;
|
||||
import io.github.thebusybiscuit.slimefun4.api.events.AsyncProfileLoadEvent;
|
||||
import io.github.thebusybiscuit.slimefun4.api.gps.Waypoint;
|
||||
import io.github.thebusybiscuit.slimefun4.api.items.HashedArmorpiece;
|
||||
import io.github.thebusybiscuit.slimefun4.api.items.ItemState;
|
||||
import io.github.thebusybiscuit.slimefun4.api.researches.Research;
|
||||
import io.github.thebusybiscuit.slimefun4.core.attributes.ProtectionType;
|
||||
import io.github.thebusybiscuit.slimefun4.core.attributes.ProtectiveArmor;
|
||||
@ -324,10 +325,18 @@ public class PlayerProfile {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
// returns the amount of researches with at least 1 enabled item
|
||||
private int nonEmptyResearches() {
|
||||
return (int) Slimefun.getRegistry().getResearches()
|
||||
.stream()
|
||||
.filter(research -> research.getAffectedItems().stream().anyMatch(item -> item.getState() == ItemState.ENABLED))
|
||||
.count();
|
||||
}
|
||||
|
||||
public @Nonnull String getTitle() {
|
||||
List<String> titles = Slimefun.getRegistry().getResearchRanks();
|
||||
|
||||
float fraction = (float) researches.size() / Slimefun.getRegistry().getResearches().size();
|
||||
float fraction = (float) researches.size() / nonEmptyResearches();
|
||||
int index = (int) (fraction * (titles.size() - 1));
|
||||
|
||||
return titles.get(index);
|
||||
@ -336,7 +345,7 @@ public class PlayerProfile {
|
||||
public void sendStats(@Nonnull CommandSender sender) {
|
||||
Set<Research> unlockedResearches = getResearches();
|
||||
int levels = unlockedResearches.stream().mapToInt(Research::getCost).sum();
|
||||
int allResearches = Slimefun.getRegistry().getResearches().size();
|
||||
int allResearches = nonEmptyResearches();
|
||||
|
||||
float progress = Math.round(((unlockedResearches.size() * 100.0F) / allResearches) * 100.0F) / 100.0F;
|
||||
|
||||
|
@ -7,12 +7,12 @@ import javax.annotation.Nullable;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import io.github.thebusybiscuit.slimefun4.api.events.ResearchUnlockEvent;
|
||||
import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile;
|
||||
import io.github.thebusybiscuit.slimefun4.core.guide.options.SlimefunGuideSettings;
|
||||
import io.github.thebusybiscuit.slimefun4.core.services.sounds.SoundEffect;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
|
||||
import io.github.thebusybiscuit.slimefun4.utils.FireworkUtils;
|
||||
|
||||
@ -64,7 +64,7 @@ public class PlayerResearchTask implements Consumer<PlayerProfile> {
|
||||
|
||||
if (!isInstant) {
|
||||
Slimefun.runSync(() -> {
|
||||
p.playSound(p.getLocation(), Sound.ENTITY_BAT_TAKEOFF, 0.7F, 1F);
|
||||
SoundEffect.PLAYER_RESEARCHING_SOUND.playFor(p);
|
||||
Slimefun.getLocalization().sendMessage(p, "messages.research.progress", true, msg -> msg.replace(PLACEHOLDER, research.getName(p)).replace("%progress%", "0%"));
|
||||
}, 5L);
|
||||
}
|
||||
@ -93,7 +93,7 @@ public class PlayerResearchTask implements Consumer<PlayerProfile> {
|
||||
int index = i;
|
||||
|
||||
Slimefun.runSync(() -> {
|
||||
p.playSound(p.getLocation(), Sound.ENTITY_BAT_TAKEOFF, 0.7F, 1);
|
||||
SoundEffect.PLAYER_RESEARCHING_SOUND.playFor(p);
|
||||
|
||||
Slimefun.getLocalization().sendMessage(p, "messages.research.progress", true, msg -> {
|
||||
String progress = RESEARCH_PROGRESS[index - 1] + "%";
|
||||
@ -125,5 +125,4 @@ public class PlayerResearchTask implements Consumer<PlayerProfile> {
|
||||
callback.accept(p);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -65,7 +65,6 @@ public final class SlimefunRegistry {
|
||||
private final Set<UUID> researchingPlayers = Collections.synchronizedSet(new HashSet<>());
|
||||
|
||||
// TODO: Move this all into a proper "config cache" class
|
||||
private boolean backwardsCompatibility;
|
||||
private boolean automaticallyLoadItems;
|
||||
private boolean enableResearches;
|
||||
private boolean freeCreativeResearches;
|
||||
@ -109,7 +108,6 @@ public final class SlimefunRegistry {
|
||||
|
||||
researchRanks.addAll(cfg.getStringList("research-ranks"));
|
||||
|
||||
backwardsCompatibility = cfg.getBoolean("options.backwards-compatibility");
|
||||
freeCreativeResearches = cfg.getBoolean("researches.free-in-creative-mode");
|
||||
researchFireworks = cfg.getBoolean("researches.enable-fireworks");
|
||||
disableLearningAnimation = cfg.getBoolean("researches.disable-learning-animation");
|
||||
@ -129,29 +127,6 @@ public final class SlimefunRegistry {
|
||||
return automaticallyLoadItems;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns whether backwards-compatibility is enabled.
|
||||
* Backwards compatibility allows Slimefun to recognize items from older versions but comes
|
||||
* at a huge performance cost.
|
||||
*
|
||||
* @return Whether backwards compatibility is enabled
|
||||
*/
|
||||
public boolean isBackwardsCompatible() {
|
||||
return backwardsCompatibility;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method sets the status of backwards compatibility.
|
||||
* Backwards compatibility allows Slimefun to recognize items from older versions but comes
|
||||
* at a huge performance cost.
|
||||
*
|
||||
* @param compatible
|
||||
* Whether backwards compatibility should be enabled
|
||||
*/
|
||||
public void setBackwardsCompatible(boolean compatible) {
|
||||
backwardsCompatibility = compatible;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will make any {@link SlimefunItem} which is registered automatically
|
||||
* call {@link SlimefunItem#load()}.
|
||||
|
@ -59,10 +59,11 @@ public interface DamageableItem extends ItemAttribute {
|
||||
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
|
||||
if (!meta.isUnbreakable()) {
|
||||
if (meta != null && !meta.isUnbreakable()) {
|
||||
Damageable damageable = (Damageable) meta;
|
||||
|
||||
if (damageable.getDamage() >= item.getType().getMaxDurability()) {
|
||||
// No need for a SoundEffect equivalent here since this is supposed to be a vanilla sound.
|
||||
p.playSound(p.getEyeLocation(), Sound.ENTITY_ITEM_BREAK, 1, 1);
|
||||
item.setAmount(0);
|
||||
} else {
|
||||
|
@ -0,0 +1,33 @@
|
||||
package io.github.thebusybiscuit.slimefun4.core.attributes;
|
||||
|
||||
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
|
||||
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
/**
|
||||
* Implement this interface for any {@link SlimefunItem} to prevent
|
||||
* cargo using only its ID when comparing. #canStack is used when
|
||||
* comparing stacks
|
||||
*
|
||||
* @author Sefiraat
|
||||
*/
|
||||
public interface DistinctiveItem extends ItemAttribute {
|
||||
|
||||
/**
|
||||
* This method is called by {@link SlimefunUtils#isItemSimilar} when two {@link SlimefunItemStack}
|
||||
* IDs match on a DistinctiveItem and should return if the two items can stack
|
||||
* with one another.
|
||||
*
|
||||
* @param itemMetaOne
|
||||
* The {@link ItemMeta} of the first stack being compared.
|
||||
* @param itemMetaTwo
|
||||
* The {@link ItemMeta} of the second stack being compared.
|
||||
*
|
||||
* @return Whether the two {@link ItemMeta}s are stackable
|
||||
*/
|
||||
boolean canStack(@Nonnull ItemMeta itemMetaOne, @Nonnull ItemMeta itemMetaTwo);
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package io.github.thebusybiscuit.slimefun4.core.attributes;
|
||||
|
||||
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem;
|
||||
import io.github.thebusybiscuit.slimefun4.core.attributes.interactions.InteractionResult;
|
||||
import org.bukkit.Location;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
/**
|
||||
* Implement this interface for any {@link SlimefunItem} to provide methods for
|
||||
* external code to 'interact' with the item when placed as a block in the world.
|
||||
*
|
||||
* @author Sefiraat
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface ExternallyInteractable {
|
||||
|
||||
/**
|
||||
* This method should be used by the implementing class to fulfill the actions needed
|
||||
* when being interacted with returning the result of the interaction.
|
||||
*
|
||||
* @param location
|
||||
* The {@link Location} of the Block being targeted for the interaction.
|
||||
*
|
||||
* @return The {@link InteractionResult} denoting the result of the interaction.
|
||||
*/
|
||||
@Nonnull
|
||||
InteractionResult onInteract(@Nonnull Location location);
|
||||
|
||||
}
|
@ -0,0 +1,69 @@
|
||||
package io.github.thebusybiscuit.slimefun4.core.attributes;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
|
||||
import io.github.thebusybiscuit.slimefun4.utils.RadiationUtils;
|
||||
|
||||
/**
|
||||
* An enum of potential radiation symptoms.
|
||||
* A symptom will be applied when the minExposure
|
||||
* threshold is reached on the {@link Player}'s
|
||||
* exposure level.
|
||||
* When the {@link Player} gets above the minExposure threshold
|
||||
* the {@link PotionEffect} will be applied.
|
||||
*
|
||||
* @author Semisol
|
||||
*
|
||||
* @see RadiationUtils
|
||||
*/
|
||||
public enum RadiationSymptom {
|
||||
|
||||
SLOW(10, PotionEffectType.SLOW, 3),
|
||||
WITHER_LOW(25, PotionEffectType.WITHER, 0),
|
||||
BLINDNESS(50, PotionEffectType.BLINDNESS, 4),
|
||||
WITHER_HIGH(75, PotionEffectType.WITHER, 3),
|
||||
IMMINENT_DEATH(100, PotionEffectType.HARM, 49);
|
||||
|
||||
private final int minExposure;
|
||||
private final PotionEffect potionEffect;
|
||||
|
||||
RadiationSymptom(int minExposure, @Nonnull PotionEffectType type, int level) {
|
||||
Preconditions.checkNotNull(type, "The effect type cannot be null");
|
||||
Preconditions.checkArgument(minExposure > 0, "The minimum exposure must be greater than 0.");
|
||||
Preconditions.checkArgument(level >= 0, "The status effect level must be non-negative.");
|
||||
|
||||
this.minExposure = minExposure;
|
||||
this.potionEffect = new PotionEffect(type, Slimefun.getCfg().getOrSetDefault("options.radiation-update-interval", 1) * 20 + 20, level);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method applies the symptom to a player.
|
||||
*
|
||||
* @param p
|
||||
* The player
|
||||
*/
|
||||
public void apply(@Nonnull Player p) {
|
||||
Preconditions.checkNotNull(p, "The player cannot be null");
|
||||
p.addPotionEffect(potionEffect);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns if this symptom
|
||||
* should be applied.
|
||||
*
|
||||
* @param exposure
|
||||
* Exposure level
|
||||
*
|
||||
* @return If the symptom should be applied
|
||||
*/
|
||||
public boolean shouldApply(int exposure) {
|
||||
return exposure >= minExposure;
|
||||
}
|
||||
}
|
@ -2,6 +2,8 @@ package io.github.thebusybiscuit.slimefun4.core.attributes;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.tasks.armor.RadiationTask;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
@ -20,41 +22,53 @@ public enum Radioactivity {
|
||||
* This represents a low level of radiation.
|
||||
* It will still cause damage but will take a while before it becomes deadly.
|
||||
*/
|
||||
LOW(ChatColor.YELLOW),
|
||||
LOW(ChatColor.YELLOW, 1),
|
||||
|
||||
/**
|
||||
* This represents a medium level of radiation.
|
||||
* This can be considered the default.
|
||||
*/
|
||||
MODERATE(ChatColor.YELLOW),
|
||||
MODERATE(ChatColor.YELLOW, 2),
|
||||
|
||||
/**
|
||||
* This is a high level of radiation.
|
||||
* It will cause death if the {@link Player} does not act quickly.
|
||||
*/
|
||||
HIGH(ChatColor.DARK_GREEN),
|
||||
HIGH(ChatColor.GOLD, 3),
|
||||
|
||||
/**
|
||||
* A very high level of radiation will be deadly.
|
||||
* The {@link Player} should not take this too lightly...
|
||||
*/
|
||||
VERY_HIGH(ChatColor.RED),
|
||||
VERY_HIGH(ChatColor.RED, 5),
|
||||
|
||||
/**
|
||||
* This is the deadlies level of radiation.
|
||||
* This is the deadliest level of radiation.
|
||||
* The {@link Player} has basically no chance to protect themselves in time.
|
||||
* It will cause certain death.
|
||||
*/
|
||||
VERY_DEADLY(ChatColor.DARK_RED);
|
||||
VERY_DEADLY(ChatColor.DARK_RED, 10);
|
||||
|
||||
private final ChatColor color;
|
||||
private final int exposureModifier;
|
||||
|
||||
Radioactivity(@Nonnull ChatColor color) {
|
||||
Radioactivity(@Nonnull ChatColor color, int exposureModifier) {
|
||||
this.color = color;
|
||||
this.exposureModifier = exposureModifier;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public String getLore() {
|
||||
/**
|
||||
* This method returns the amount of exposure applied
|
||||
* to a player every run of the {@link RadiationTask}
|
||||
* for this radiation level.
|
||||
*
|
||||
* @return The exposure amount applied per run.
|
||||
*/
|
||||
public int getExposureModifier() {
|
||||
return exposureModifier;
|
||||
}
|
||||
|
||||
public @Nonnull String getLore() {
|
||||
return ChatColor.GREEN + "\u2622" + ChatColor.GRAY + " Radiation level: " + color + toString().replace('_', ' ');
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,61 @@
|
||||
package io.github.thebusybiscuit.slimefun4.core.attributes.interactions;
|
||||
|
||||
import io.github.thebusybiscuit.slimefun4.core.attributes.ExternallyInteractable;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
/**
|
||||
* This class represents the result of an interaction on an {@link ExternallyInteractable} item.
|
||||
*/
|
||||
public class InteractionResult {
|
||||
|
||||
private final boolean interactionSuccessful;
|
||||
private @Nullable String resultMessage;
|
||||
|
||||
/**
|
||||
* Creates a new InteractionResult.
|
||||
*
|
||||
* @param successful Whether the interaction was successful or not.
|
||||
*/
|
||||
@ParametersAreNonnullByDefault
|
||||
public InteractionResult(boolean successful) {
|
||||
this.interactionSuccessful = successful;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the interaction was successful or not.
|
||||
*
|
||||
* @return boolean denoting whether the interaction was successful or not.
|
||||
*/
|
||||
public boolean isInteractionSuccessful() {
|
||||
return interactionSuccessful;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a custom result message for this interaction.
|
||||
*
|
||||
* @param resultMessage The message to be sent with the Result
|
||||
*/
|
||||
public void setResultMessage(@Nullable String resultMessage) {
|
||||
this.resultMessage = resultMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this result has a result message or is null.
|
||||
*
|
||||
* @return true if a result message is present
|
||||
*/
|
||||
public boolean hasResultMessage() {
|
||||
return this.resultMessage != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the custom result message for this result or null if not set.
|
||||
*
|
||||
* @return A String of the provided custom result message.
|
||||
*/
|
||||
public @Nullable String getResultMessage() {
|
||||
return resultMessage;
|
||||
}
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
package io.github.thebusybiscuit.slimefun4.core.attributes.interactions;
|
||||
|
||||
import io.github.thebusybiscuit.slimefun4.core.attributes.ExternallyInteractable;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* This class represents the result of an interaction on an {@link ExternallyInteractable} item.
|
||||
*/
|
||||
public class ItemInteractionResult extends InteractionResult {
|
||||
|
||||
private final @Nonnull Set<ItemStack> resultItems = new HashSet<>();
|
||||
|
||||
/**
|
||||
* Creates a new InteractionResult.
|
||||
*
|
||||
* @param successful Whether the interaction was successful or not.
|
||||
*/
|
||||
public ItemInteractionResult(boolean successful) {
|
||||
super(successful);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new InteractionResult.
|
||||
*
|
||||
* @param successful Whether the interaction was successful or not.
|
||||
* @param itemStacks The {@link ItemStack}(s) that would be returned due to this interaction.
|
||||
*/
|
||||
public ItemInteractionResult(boolean successful, ItemStack... itemStacks) {
|
||||
super(successful);
|
||||
addResultItems(itemStacks);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an or several {@link ItemStack}'s into the result.
|
||||
*
|
||||
* @param itemStacks The {@link ItemStack}(s) that would be returned due to this interaction.
|
||||
*/
|
||||
public void addResultItems(ItemStack... itemStacks) {
|
||||
Collections.addAll(resultItems, itemStacks);
|
||||
}
|
||||
|
||||
/**
|
||||
* This returned whether items are included as part of the result.
|
||||
*
|
||||
* @return True if items are included in the result.
|
||||
*/
|
||||
public boolean resultedInItems() {
|
||||
return !this.resultItems.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link ItemStack}(s) produced as a result of this interaction, if any.
|
||||
*
|
||||
* @return An unmodifiable {@link Set} of {@link ItemStack}(s) created due to the interaction.
|
||||
*/
|
||||
public @Nonnull Set<ItemStack> getResultItems() {
|
||||
return Collections.unmodifiableSet(resultItems);
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
/**
|
||||
* This package contains the various possible {@link io.github.thebusybiscuit.slimefun4.core.attributes.interactions.InteractionResult}s
|
||||
* that can be returned by an {@link io.github.thebusybiscuit.slimefun4.core.attributes.ExternallyInteractable} object.
|
||||
*/
|
||||
package io.github.thebusybiscuit.slimefun4.core.attributes.interactions;
|
@ -15,6 +15,7 @@ import org.bukkit.entity.Player;
|
||||
import io.github.thebusybiscuit.slimefun4.core.commands.SlimefunCommand;
|
||||
import io.github.thebusybiscuit.slimefun4.core.commands.SubCommand;
|
||||
import io.github.thebusybiscuit.slimefun4.core.services.profiler.PerformanceInspector;
|
||||
import io.github.thebusybiscuit.slimefun4.core.services.profiler.SummaryOrderType;
|
||||
import io.github.thebusybiscuit.slimefun4.core.services.profiler.inspectors.ConsolePerformanceInspector;
|
||||
import io.github.thebusybiscuit.slimefun4.core.services.profiler.inspectors.PlayerPerformanceInspector;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
|
||||
@ -22,7 +23,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
|
||||
class TimingsCommand extends SubCommand {
|
||||
|
||||
private static final String FLAG_PREFIX = "--";
|
||||
private final Set<String> flags = new HashSet<>(Arrays.asList("verbose"));
|
||||
private final Set<String> flags = new HashSet<>(Arrays.asList("verbose", "avg", "low"));
|
||||
|
||||
@ParametersAreNonnullByDefault
|
||||
TimingsCommand(Slimefun plugin, SlimefunCommand cmd) {
|
||||
@ -30,13 +31,17 @@ class TimingsCommand extends SubCommand {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getDescription() {
|
||||
protected @Nonnull String getDescription() {
|
||||
return "commands.timings.description";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onExecute(CommandSender sender, String[] args) {
|
||||
if (sender.hasPermission("slimefun.command.timings") || sender instanceof ConsoleCommandSender) {
|
||||
public void onExecute(CommandSender sender, @Nonnull String[] args) {
|
||||
if (!sender.hasPermission("slimefun.command.timings") && !(sender instanceof ConsoleCommandSender)) {
|
||||
Slimefun.getLocalization().sendMessage(sender, "messages.no-permission", true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (hasInvalidFlags(sender, args)) {
|
||||
return;
|
||||
}
|
||||
@ -48,13 +53,18 @@ class TimingsCommand extends SubCommand {
|
||||
return;
|
||||
}
|
||||
|
||||
SummaryOrderType orderType = SummaryOrderType.HIGHEST;
|
||||
|
||||
if (hasFlag(args, "avg")) {
|
||||
orderType = SummaryOrderType.AVERAGE;
|
||||
} else if (hasFlag(args, "low")) {
|
||||
orderType = SummaryOrderType.LOWEST;
|
||||
}
|
||||
|
||||
Slimefun.getLocalization().sendMessage(sender, "commands.timings.please-wait", true);
|
||||
|
||||
PerformanceInspector inspector = inspectorOf(sender, verbose);
|
||||
PerformanceInspector inspector = inspectorOf(sender, verbose, orderType);
|
||||
Slimefun.getProfiler().requestSummary(inspector);
|
||||
} else {
|
||||
Slimefun.getLocalization().sendMessage(sender, "messages.no-permission", true);
|
||||
}
|
||||
}
|
||||
|
||||
@ParametersAreNonnullByDefault
|
||||
@ -87,12 +97,12 @@ class TimingsCommand extends SubCommand {
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
private PerformanceInspector inspectorOf(@Nonnull CommandSender sender, boolean verbose) {
|
||||
@ParametersAreNonnullByDefault
|
||||
private PerformanceInspector inspectorOf(CommandSender sender, boolean verbose, SummaryOrderType orderType) {
|
||||
if (sender instanceof Player player) {
|
||||
return new PlayerPerformanceInspector(player);
|
||||
return new PlayerPerformanceInspector(player, orderType);
|
||||
} else {
|
||||
return new ConsolePerformanceInspector(sender, verbose);
|
||||
return new ConsolePerformanceInspector(sender, verbose, orderType);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -83,18 +83,6 @@ class VersionsCommand extends SubCommand {
|
||||
|
||||
addJavaVersion(builder);
|
||||
|
||||
if (Slimefun.getRegistry().isBackwardsCompatible()) {
|
||||
// @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);
|
||||
}
|
||||
|
||||
builder.append("\n").event((HoverEvent) null);
|
||||
addPluginVersions(builder);
|
||||
|
||||
|
@ -6,7 +6,6 @@ import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.SkullMeta;
|
||||
@ -15,6 +14,7 @@ import io.github.bakedlibs.dough.common.ChatColors;
|
||||
import io.github.bakedlibs.dough.common.CommonPatterns;
|
||||
import io.github.bakedlibs.dough.items.CustomItemStack;
|
||||
import io.github.thebusybiscuit.slimefun4.core.services.github.Contributor;
|
||||
import io.github.thebusybiscuit.slimefun4.core.services.sounds.SoundEffect;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
|
||||
import io.github.thebusybiscuit.slimefun4.utils.ChatUtils;
|
||||
import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils;
|
||||
@ -36,7 +36,7 @@ final class ContributorsMenu {
|
||||
ChestMenu menu = new ChestMenu(Slimefun.getLocalization().getMessage(p, "guide.title.credits"));
|
||||
|
||||
menu.setEmptySlotsClickable(false);
|
||||
menu.addMenuOpeningHandler(pl -> pl.playSound(pl.getLocation(), Sound.BLOCK_NOTE_BLOCK_HARP, 0.7F, 0.7F));
|
||||
menu.addMenuOpeningHandler(SoundEffect.GUIDE_CONTRIBUTORS_OPEN_SOUND::playFor);
|
||||
|
||||
ChestMenuUtils.drawBackground(menu, 0, 2, 3, 4, 5, 6, 7, 8, 45, 47, 48, 49, 50, 51, 53);
|
||||
|
||||
|
@ -6,7 +6,6 @@ import java.util.Optional;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
@ -15,6 +14,7 @@ import io.github.bakedlibs.dough.items.CustomItemStack;
|
||||
import io.github.thebusybiscuit.slimefun4.api.SlimefunAddon;
|
||||
import io.github.thebusybiscuit.slimefun4.api.events.PlayerLanguageChangeEvent;
|
||||
import io.github.thebusybiscuit.slimefun4.core.services.localization.Language;
|
||||
import io.github.thebusybiscuit.slimefun4.core.services.sounds.SoundEffect;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
|
||||
import io.github.thebusybiscuit.slimefun4.utils.ChatUtils;
|
||||
import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils;
|
||||
@ -79,7 +79,7 @@ class PlayerLanguageOption implements SlimefunGuideOption<String> {
|
||||
ChestMenu menu = new ChestMenu(Slimefun.getLocalization().getMessage(p, "guide.title.languages"));
|
||||
|
||||
menu.setEmptySlotsClickable(false);
|
||||
menu.addMenuOpeningHandler(pl -> pl.playSound(pl.getLocation(), Sound.BLOCK_NOTE_BLOCK_HARP, 0.7F, 0.7F));
|
||||
menu.addMenuOpeningHandler(SoundEffect.GUIDE_LANGUAGE_OPEN_SOUND::playFor);
|
||||
|
||||
for (int i = 0; i < 9; i++) {
|
||||
if (i == 1) {
|
||||
|
@ -10,7 +10,6 @@ import javax.annotation.ParametersAreNonnullByDefault;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
@ -21,6 +20,7 @@ import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideMode;
|
||||
import io.github.thebusybiscuit.slimefun4.core.services.LocalizationService;
|
||||
import io.github.thebusybiscuit.slimefun4.core.services.github.GitHubService;
|
||||
import io.github.thebusybiscuit.slimefun4.core.services.localization.Language;
|
||||
import io.github.thebusybiscuit.slimefun4.core.services.sounds.SoundEffect;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
|
||||
import io.github.thebusybiscuit.slimefun4.utils.ChatUtils;
|
||||
import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils;
|
||||
@ -63,7 +63,7 @@ public final class SlimefunGuideSettings {
|
||||
ChestMenu menu = new ChestMenu(Slimefun.getLocalization().getMessage(p, "guide.title.settings"));
|
||||
|
||||
menu.setEmptySlotsClickable(false);
|
||||
menu.addMenuOpeningHandler(pl -> pl.playSound(pl.getLocation(), Sound.BLOCK_NOTE_BLOCK_HARP, 0.7F, 0.7F));
|
||||
menu.addMenuOpeningHandler(SoundEffect.GUIDE_OPEN_SETTING_SOUND::playFor);
|
||||
|
||||
ChestMenuUtils.drawBackground(menu, BACKGROUND_SLOTS);
|
||||
|
||||
|
@ -9,7 +9,10 @@ import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
@ -105,11 +108,21 @@ public abstract class MultiBlockMachine extends SlimefunItem implements NotPlace
|
||||
public void load() {
|
||||
super.load();
|
||||
|
||||
for (ItemStack recipeItem : displayRecipes) {
|
||||
SlimefunItem item = SlimefunItem.getByItem(recipeItem);
|
||||
Preconditions.checkArgument(displayRecipes.size() % 2 == 0, "This MultiBlockMachine's display recipes were illegally modified!");
|
||||
|
||||
if (item == null || !item.isDisabled()) {
|
||||
recipes.add(new ItemStack[] { recipeItem });
|
||||
for (int i = 0; i < displayRecipes.size(); i += 2) {
|
||||
ItemStack inputStack = displayRecipes.get(i);
|
||||
ItemStack outputStack = null;
|
||||
if (displayRecipes.size() >= i + 2) {
|
||||
outputStack = displayRecipes.get(i + 1);
|
||||
}
|
||||
|
||||
SlimefunItem inputItem = SlimefunItem.getByItem(inputStack);
|
||||
SlimefunItem outputItem = SlimefunItem.getByItem(outputStack);
|
||||
// If the input/output is not a Slimefun item or it's not disabled then it's valid.
|
||||
if ((inputItem == null || !inputItem.isDisabled()) && (outputItem == null || !outputItem.isDisabled())) {
|
||||
recipes.add(new ItemStack[] { inputStack });
|
||||
recipes.add(new ItemStack[] { outputStack });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package io.github.thebusybiscuit.slimefun4.core.services;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -77,6 +77,7 @@ class ContributionsConnector extends GitHubConnector {
|
||||
aliases.put("NCBPFluffyBear", "FluffyBear_");
|
||||
aliases.put("martinbrom", "OneTime97");
|
||||
aliases.put("LilBC", "Lil_BC");
|
||||
aliases.put("st392", "BlueWood");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -38,4 +38,10 @@ public interface PerformanceInspector {
|
||||
*/
|
||||
boolean isVerbose();
|
||||
|
||||
/**
|
||||
* The order type for the summary of timings.
|
||||
*
|
||||
* @return The order type for the summary of timings.
|
||||
*/
|
||||
@Nonnull SummaryOrderType getOrderType();
|
||||
}
|
||||
|
@ -1,12 +1,10 @@
|
||||
package io.github.thebusybiscuit.slimefun4.core.services.profiler;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
@ -64,13 +62,18 @@ class PerformanceSummary {
|
||||
summarizeTimings(totalTickedBlocks, "block", sender, items, entry -> {
|
||||
int count = profiler.getBlocksOfId(entry.getKey());
|
||||
String time = NumberUtils.getAsMillis(entry.getValue());
|
||||
String message = entry.getKey() + " - " + count + "x (%s)";
|
||||
|
||||
if (count <= 1) {
|
||||
return String.format(message, time);
|
||||
}
|
||||
|
||||
if (count > 1) {
|
||||
String average = NumberUtils.getAsMillis(entry.getValue() / count);
|
||||
|
||||
return entry.getKey() + " - " + count + "x (" + time + " | avg: " + average + ')';
|
||||
if (sender.getOrderType() == SummaryOrderType.AVERAGE) {
|
||||
return String.format(message, average + " | total: " + time);
|
||||
} else {
|
||||
return entry.getKey() + " - " + count + "x (" + time + ')';
|
||||
return String.format(message, time + " | avg: " + average);
|
||||
}
|
||||
});
|
||||
|
||||
@ -91,8 +94,8 @@ class PerformanceSummary {
|
||||
|
||||
@ParametersAreNonnullByDefault
|
||||
private void summarizeTimings(int count, String name, PerformanceInspector inspector, Map<String, Long> map, Function<Map.Entry<String, Long>, String> formatter) {
|
||||
Stream<Map.Entry<String, Long>> stream = map.entrySet().stream();
|
||||
List<Entry<String, Long>> results = stream.sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())).collect(Collectors.toList());
|
||||
Set<Entry<String, Long>> entrySet = map.entrySet();
|
||||
List<Entry<String, Long>> results = inspector.getOrderType().sort(profiler, entrySet);
|
||||
String prefix = count + " " + name + (count != 1 ? 's' : "");
|
||||
|
||||
if (inspector instanceof PlayerPerformanceInspector playerPerformanceInspector) {
|
||||
@ -181,22 +184,15 @@ class PerformanceSummary {
|
||||
rest--;
|
||||
}
|
||||
|
||||
builder.append(ChatColor.DARK_GRAY);
|
||||
|
||||
for (int i = 0; i < rest; i++) {
|
||||
builder.append(':');
|
||||
}
|
||||
|
||||
builder.append(" - ");
|
||||
|
||||
builder.append(rating.getColor() + ChatUtils.humanize(rating.name()));
|
||||
|
||||
builder.append(ChatColor.GRAY);
|
||||
builder.append(" (");
|
||||
builder.append(NumberUtils.roundDecimalNumber(percentage));
|
||||
builder.append("%)");
|
||||
builder.append(ChatColor.DARK_GRAY)
|
||||
.append(":".repeat(Math.max(0, rest)))
|
||||
.append(" - ")
|
||||
.append(rating.getColor()).append(ChatUtils.humanize(rating.name()))
|
||||
.append(ChatColor.GRAY)
|
||||
.append(" (")
|
||||
.append(NumberUtils.roundDecimalNumber(percentage))
|
||||
.append("%)");
|
||||
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,55 @@
|
||||
package io.github.thebusybiscuit.slimefun4.core.services.profiler;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Holds the different types of ordering for summaries.
|
||||
*
|
||||
* @author Walshy
|
||||
*/
|
||||
public enum SummaryOrderType {
|
||||
|
||||
/**
|
||||
* Sort by highest to the lowest total timings
|
||||
*/
|
||||
HIGHEST,
|
||||
/**
|
||||
* Sort by lowest to the highest total timings
|
||||
*/
|
||||
LOWEST,
|
||||
/**
|
||||
* Sort by average timings (highest to lowest)
|
||||
*/
|
||||
AVERAGE;
|
||||
|
||||
@ParametersAreNonnullByDefault
|
||||
List<Map.Entry<String, Long>> sort(SlimefunProfiler profiler, Set<Map.Entry<String, Long>> entrySet) {
|
||||
switch(this) {
|
||||
case HIGHEST:
|
||||
return entrySet.stream()
|
||||
.sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
|
||||
.collect(Collectors.toList());
|
||||
case LOWEST:
|
||||
return entrySet.stream()
|
||||
.sorted(Comparator.comparingLong(Map.Entry::getValue))
|
||||
.collect(Collectors.toList());
|
||||
default:
|
||||
final Map<String, Long> map = new HashMap<>();
|
||||
for (Map.Entry<String, Long> entry : entrySet) {
|
||||
int count = profiler.getBlocksOfId(entry.getKey());
|
||||
long avg = count > 0 ? entry.getValue() / count : entry.getValue();
|
||||
|
||||
map.put(entry.getKey(), avg);
|
||||
}
|
||||
return map.entrySet().stream()
|
||||
.sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
}
|
@ -1,7 +1,9 @@
|
||||
package io.github.thebusybiscuit.slimefun4.core.services.profiler.inspectors;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
import io.github.thebusybiscuit.slimefun4.core.services.profiler.SummaryOrderType;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.ConsoleCommandSender;
|
||||
@ -28,35 +30,61 @@ public class ConsolePerformanceInspector implements PerformanceInspector {
|
||||
*/
|
||||
private final boolean verbose;
|
||||
|
||||
/**
|
||||
* The order type of the timings.
|
||||
*/
|
||||
private final SummaryOrderType orderType;
|
||||
|
||||
/**
|
||||
* This creates a new {@link ConsolePerformanceInspector} for the given {@link CommandSender}.
|
||||
*
|
||||
* @param console
|
||||
* The {@link CommandSender}, preferabbly a {@link ConsoleCommandSender}
|
||||
* The {@link CommandSender}, preferably a {@link ConsoleCommandSender}
|
||||
* @param verbose
|
||||
* Whether the summary will be verbose or not
|
||||
* @param orderType
|
||||
* The {@link SummaryOrderType} of the timings
|
||||
*/
|
||||
public ConsolePerformanceInspector(@Nonnull CommandSender console, boolean verbose) {
|
||||
@ParametersAreNonnullByDefault
|
||||
public ConsolePerformanceInspector(CommandSender console, boolean verbose, SummaryOrderType orderType) {
|
||||
Validate.notNull(console, "CommandSender cannot be null");
|
||||
Validate.notNull(orderType, "SummaryOrderType cannot be null");
|
||||
|
||||
this.console = console;
|
||||
this.verbose = verbose;
|
||||
this.orderType = orderType;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean isValid() {
|
||||
// The console is always "online".
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean isVerbose() {
|
||||
return verbose;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public @Nonnull SummaryOrderType getOrderType() {
|
||||
return orderType;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void sendMessage(@Nonnull String msg) {
|
||||
console.sendMessage(msg);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import java.util.UUID;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import io.github.thebusybiscuit.slimefun4.core.services.profiler.SummaryOrderType;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
@ -27,34 +28,62 @@ public class PlayerPerformanceInspector implements PerformanceInspector {
|
||||
*/
|
||||
private final UUID uuid;
|
||||
|
||||
/**
|
||||
* The order type of the timings.
|
||||
*/
|
||||
private final SummaryOrderType orderType;
|
||||
|
||||
/**
|
||||
* This creates a new {@link PlayerPerformanceInspector} for the given {@link Player}.
|
||||
*
|
||||
* @param player
|
||||
* The {@link Player}
|
||||
* @param orderType
|
||||
* The {@link SummaryOrderType} of the timings
|
||||
*/
|
||||
public PlayerPerformanceInspector(@Nonnull Player player) {
|
||||
public PlayerPerformanceInspector(@Nonnull Player player, @Nonnull SummaryOrderType orderType) {
|
||||
Validate.notNull(player, "Player cannot be null");
|
||||
Validate.notNull(orderType, "SummaryOrderType cannot be null");
|
||||
|
||||
this.uuid = player.getUniqueId();
|
||||
this.orderType = orderType;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Player getPlayer() {
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
private @Nullable Player getPlayer() {
|
||||
return Bukkit.getPlayer(uuid);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean isValid() {
|
||||
Player player = getPlayer();
|
||||
return player != null && player.isOnline();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean isVerbose() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public @Nonnull SummaryOrderType getOrderType() {
|
||||
return orderType;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void sendMessage(@Nonnull String msg) {
|
||||
Player player = getPlayer();
|
||||
|
@ -0,0 +1,38 @@
|
||||
package io.github.thebusybiscuit.slimefun4.core.services.sounds;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
/**
|
||||
* This structure class holds configured values for a {@link SoundEffect}.
|
||||
*
|
||||
* @author TheBusyBiscuit
|
||||
*
|
||||
* @see SoundService
|
||||
* @see SoundEffect
|
||||
*
|
||||
*/
|
||||
public class SoundConfiguration {
|
||||
|
||||
private final String sound;
|
||||
private final float volume;
|
||||
private final float pitch;
|
||||
|
||||
protected SoundConfiguration(@Nonnull String sound, float volume, float pitch) {
|
||||
this.sound = sound;
|
||||
this.volume = volume;
|
||||
this.pitch = pitch;
|
||||
}
|
||||
|
||||
public @Nonnull String getSoundId() {
|
||||
return sound;
|
||||
}
|
||||
|
||||
public float getVolume() {
|
||||
return volume;
|
||||
}
|
||||
|
||||
public float getPitch() {
|
||||
return pitch;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,218 @@
|
||||
package io.github.thebusybiscuit.slimefun4.core.services.sounds;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.SoundCategory;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
/**
|
||||
* This enum holds references to all our sounds.
|
||||
*
|
||||
* @author TheBusyBiscuit
|
||||
* @author J3fftw1
|
||||
*
|
||||
* @see SoundService
|
||||
* @see SoundConfiguration
|
||||
*
|
||||
*/
|
||||
public enum SoundEffect {
|
||||
|
||||
ANCIENT_ALTAR_ITEM_CHECK_SOUND(Sound.ENTITY_ENDERMAN_TELEPORT, 1F, 2F),
|
||||
ANCIENT_ALTAR_ITEM_DROP_SOUND(Sound.ENTITY_ZOMBIE_ATTACK_IRON_DOOR, 1F, 1F),
|
||||
ANCIENT_ALTAR_ITEM_PICK_UP_SOUND(Sound.ENTITY_ITEM_PICKUP, 1F, 1F),
|
||||
ANCIENT_ALTAR_FINISH_SOUND(Sound.ENTITY_ZOMBIE_VILLAGER_CURE, 1F, 1F),
|
||||
ANCIENT_ALTAR_START_SOUND(Sound.ENTITY_ILLUSIONER_PREPARE_MIRROR, 1F, 1F),
|
||||
ANCIENT_PEDESTAL_ITEM_PLACE_SOUND(Sound.ENTITY_ITEM_PICKUP, 0.5F, 0.5F),
|
||||
ARMOR_FORGE_FINISH_SOUND(Sound.BLOCK_ANVIL_USE, 1F, 1F),
|
||||
ARMOR_FORGE_WORKING_SOUND(Sound.ENTITY_ARROW_HIT_PLAYER, 1F, 1F),
|
||||
AUTO_CRAFTER_GUI_CLICK_SOUND(Sound.UI_BUTTON_CLICK, 1F, 1F),
|
||||
AUTO_CRAFTER_UPDATE_RECIPE(Sound.UI_BUTTON_CLICK, 1F, 1F),
|
||||
AUTOMATED_PANNING_MACHINE_FAIL_SOUND(Sound.ENTITY_ARMOR_STAND_BREAK, 1F, 1F),
|
||||
AUTOMATED_PANNING_MACHINE_SUCCESS_SOUND(Sound.ENTITY_ARROW_HIT_PLAYER, 1F, 1F),
|
||||
BEE_BOOTS_FALL_SOUND(Sound.BLOCK_HONEY_BLOCK_FALL, 1F, 1F),
|
||||
BACKPACK_CLOSE_SOUND(Sound.ENTITY_HORSE_ARMOR, 1F, 1F),
|
||||
BACKPACK_OPEN_SOUND(Sound.ENTITY_HORSE_ARMOR, 1F, 1F),
|
||||
COMPOSTER_COMPOST_SOUND(Sound.ENTITY_ARROW_HIT_PLAYER, 1F, 1F),
|
||||
COMPRESSOR_CRAFT_SOUND(Sound.ENTITY_ARROW_HIT_PLAYER, 1F, 1F),
|
||||
COMPRESSOR_CRAFT_CONTRACT_SOUND(Sound.BLOCK_PISTON_CONTRACT, 1F, 1F),
|
||||
COMPRESSOR_CRAFT_EXTEND_SOUND(Sound.BLOCK_PISTON_EXTEND, 1F, 1F),
|
||||
COOLER_CONSUME_SOUND(Sound.ENTITY_GENERIC_DRINK, 1F, 1F),
|
||||
CRUCIBLE_ADD_WATER_SOUND(Sound.ENTITY_PLAYER_SPLASH, 1F, 1F),
|
||||
CRUCIBLE_ADD_LAVA_SOUND(Sound.BLOCK_LAVA_POP, 1F , 1F),
|
||||
CRUCIBLE_BLOCK_BREAK_SOUND(Sound.BLOCK_METAL_BREAK, 1F, 1F),
|
||||
CRUCIBLE_GENERATE_LIQUID_SOUND(Sound.BLOCK_LAVA_EXTINGUISH, 1F, 1F),
|
||||
CRUCIBLE_INTERACT_SOUND(Sound.ENTITY_ARROW_HIT_PLAYER, 1F, 1F),
|
||||
CRUCIBLE_PLACE_LAVA_SOUND(Sound.BLOCK_LAVA_POP, 1F , 1F),
|
||||
CRUCIBLE_PLACE_WATER_SOUND(Sound.ENTITY_PLAYER_SPLASH, 1F, 1F),
|
||||
DEBUG_FISH_CLICK_SOUND(Sound.BLOCK_BAMBOO_PLACE, 1F, 1F),
|
||||
DIET_COOKIE_CONSUME_SOUND(Sound.ENTITY_GENERIC_EAT, 1F, 1F),
|
||||
ENCHANTMENT_RUNE_ADD_ENCHANT_SOUND(Sound.ENTITY_ZOMBIE_VILLAGER_CURE, 1F, 1F),
|
||||
ENDER_BACKPACK_OPEN_SOUND(Sound.ENTITY_ENDERMAN_TELEPORT, 1F, 1F),
|
||||
ENHANCED_CRAFTING_TABLE_CRAFT_SOUND(Sound.BLOCK_WOODEN_BUTTON_CLICK_ON, 1F, 1F),
|
||||
ELYTRA_CAP_IMPACT_SOUND(Sound.BLOCK_STONE_HIT, 1F, 1F),
|
||||
EXPLOSIVE_BOW_HIT_SOUND(Sound.ENTITY_GENERIC_EXPLODE, 1F, 1F),
|
||||
EXPLOSIVE_TOOL_EXPLODE_SOUND(Sound.ENTITY_GENERIC_EXPLODE, 0.2F, 1F),
|
||||
FISHERMAN_ANDROID_FISHING_SOUND(Sound.ENTITY_PLAYER_SPLASH, 0.3F, 0.7F),
|
||||
FLASK_OF_KNOWLEDGE_FILLUP_SOUND(Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1F, 0.5F),
|
||||
GUIDE_BUTTON_CLICK_SOUND(Sound.ITEM_BOOK_PAGE_TURN, 1F, 1F),
|
||||
GUIDE_CONTRIBUTORS_OPEN_SOUND(Sound.BLOCK_NOTE_BLOCK_HARP, 0.7F, 0.7F),
|
||||
GUIDE_LANGUAGE_OPEN_SOUND(Sound.BLOCK_NOTE_BLOCK_HARP, 0.7F, 0.7F),
|
||||
GUIDE_OPEN_SETTING_SOUND(Sound.BLOCK_NOTE_BLOCK_HARP, 0.7F, 0.7F),
|
||||
GRIND_STONE_INTERACT_SOUND(Sound.BLOCK_WOODEN_BUTTON_CLICK_ON, 1F, 1F),
|
||||
IGNITION_CHAMBER_USE_FLINT_AND_STEEL_SOUND(Sound.ENTITY_ITEM_BREAK, 1F, 1F),
|
||||
INFUSED_HOPPER_TELEPORT_SOUND(Sound.ENTITY_ENDERMAN_TELEPORT, 0.5F, 2F),
|
||||
INFUSED_MAGNET_TELEPORT_SOUND(Sound.ENTITY_ENDERMAN_TELEPORT, 0.25F, 0.9F),
|
||||
IRON_GOLEM_ASSEMBLER_ASSEMBLE_SOUND(Sound.ENTITY_IRON_GOLEM_REPAIR, 0.5F, 1F),
|
||||
JETBOOTS_THRUST_SOUND(Sound.ENTITY_TNT_PRIMED, 0.25F, 1F),
|
||||
JETPACK_THRUST_SOUND(Sound.ENTITY_GENERIC_EXPLODE, 0.25F, 1F),
|
||||
JUICER_USE_SOUND(Sound.ENTITY_PLAYER_SPLASH, 1F, 1F),
|
||||
LIMITED_USE_ITEM_BREAK_SOUND(Sound.ENTITY_ITEM_BREAK, 1F, 1F),
|
||||
MAGICAL_EYE_OF_ENDER_USE_SOUND(Sound.ENTITY_ENDERMAN_TELEPORT, 1F, 1F),
|
||||
MAGIC_SUGAR_CONSUME_SOUND(Sound.ENTITY_GENERIC_EAT, 1F, 1F),
|
||||
MAGIC_WORKBENCH_FINISH_SOUND(Sound.ENTITY_ARROW_HIT_PLAYER, 1F, 1F),
|
||||
MAGIC_WORKBENCH_START_ANIMATION_SOUND(Sound.BLOCK_WOODEN_BUTTON_CLICK_ON, 1F, 1F),
|
||||
MINER_ANDROID_BLOCK_GENERATION_SOUND(Sound.BLOCK_FIRE_EXTINGUISH, 0.075F, 0.8F),
|
||||
MINING_TASK_SOUND(Sound.ENTITY_ARROW_HIT_PLAYER, 0.2F, 1F),
|
||||
ORE_WASHER_WASH_SOUND(Sound.ENTITY_PLAYER_SPLASH, 1F, 1F),
|
||||
PLAYER_RESEARCHING_SOUND(Sound.ENTITY_BAT_TAKEOFF, 0.7F, 1F),
|
||||
PORTABLE_DUSTBIN_OPEN_SOUND(Sound.BLOCK_ANVIL_LAND, 1F, 1F),
|
||||
PORTABLE_CRAFTER_OPEN_SOUND(Sound.BLOCK_WOODEN_BUTTON_CLICK_ON, 1F, 1F),
|
||||
PRESSURE_CHAMBER_FINISH_SOUND(Sound.ENTITY_ARROW_HIT_PLAYER, 1F, 1F),
|
||||
PRESSURE_CHAMBER_WORKING_SOUND(Sound.ENTITY_TNT_PRIMED, 1F, 1F),
|
||||
PROGRAMMABLE_ANDROID_SCRIPT_DOWNLOAD_SOUND(Sound.BLOCK_NOTE_BLOCK_HAT, 0.7F, 0.7F),
|
||||
SLIME_BOOTS_FALL_SOUND(Sound.BLOCK_SLIME_BLOCK_FALL, 1F, 1F),
|
||||
TELEPORTATION_MANAGER_OPEN_GUI(Sound.UI_BUTTON_CLICK, 1F, 1F),
|
||||
GPS_NETWORK_ADD_WAYPOINT(Sound.BLOCK_NOTE_BLOCK_PLING, 1F, 1F),
|
||||
GPS_NETWORK_CREATE_WAYPOINT(Sound.BLOCK_NOTE_BLOCK_PLING, 0.5F, 1F),
|
||||
GPS_NETWORK_OPEN_PANEL_SOUND(Sound.UI_BUTTON_CLICK, 1F, 1F),
|
||||
SMELTERY_CRAFT_SOUND(Sound.BLOCK_LAVA_POP, 1F, 1F),
|
||||
SOULBOUND_RUNE_RITUAL_SOUND(Sound.ENTITY_GENERIC_EXPLODE, 0.3F, 1F),
|
||||
SPLINT_CONSUME_SOUND(Sound.ENTITY_SKELETON_HURT, 1F, 1F),
|
||||
STOMPER_BOOTS_STOMP_SOUND(Sound.ENTITY_ZOMBIE_BREAK_WOODEN_DOOR, 1F, 2F),
|
||||
TAPE_MEASURE_MEASURE_SOUND(Sound.ITEM_BOOK_PUT, 1, 0.7F),
|
||||
TOME_OF_KNOWLEDGE_USE_SOUND(Sound.ENTITY_PLAYER_LEVELUP, 1F, 1F),
|
||||
TELEPORT_UPDATE_SOUND(Sound.BLOCK_BEACON_AMBIENT, 1F, 0.6F),
|
||||
TELEPORT_SOUND(Sound.BLOCK_BEACON_ACTIVATE, 1F, 1F),
|
||||
VAMPIRE_BLADE_HEALING_SOUND(Sound.ENTITY_ARROW_HIT_PLAYER, 0.7F, 0.7F),
|
||||
VANILLA_AUTO_CRAFTER_UPDATE_RECIPE_SOUND(Sound.UI_BUTTON_CLICK, 1F, 1F),
|
||||
VILLAGER_RUNE_TRANSFORM_SOUND(Sound.ENTITY_VILLAGER_CELEBRATE, 1F, 1.4F),
|
||||
VITAMINS_CONSUME_SOUND(Sound.ENTITY_GENERIC_EAT, 1F, 1F),
|
||||
WIND_STAFF_USE_SOUND(Sound.ENTITY_TNT_PRIMED, 1F, 1F);
|
||||
|
||||
private final String defaultSound;
|
||||
private final float defaultVolume;
|
||||
private final float defaultPitch;
|
||||
|
||||
SoundEffect(@Nonnull String sound, float volume, float pitch) {
|
||||
Preconditions.checkNotNull(sound, "The Sound id cannot be null!");
|
||||
Preconditions.checkArgument(volume >= 0, "The volume cannot be a negative number.");
|
||||
Preconditions.checkArgument(pitch >= 0.5, "A pitch below 0.5 has no effect on the sound.");
|
||||
|
||||
this.defaultSound = sound;
|
||||
this.defaultVolume = volume;
|
||||
this.defaultPitch = pitch;
|
||||
}
|
||||
|
||||
SoundEffect(@Nonnull Sound sound, float volume, float pitch) {
|
||||
Preconditions.checkNotNull(sound, "The Sound id cannot be null!");
|
||||
Preconditions.checkArgument(volume >= 0, "The volume cannot be a negative number.");
|
||||
Preconditions.checkArgument(pitch >= 0.5, "A pitch below 0.5 has no effect on the sound.");
|
||||
|
||||
this.defaultSound = sound.getKey().getKey();
|
||||
this.defaultVolume = volume;
|
||||
this.defaultPitch = pitch;
|
||||
}
|
||||
|
||||
private @Nullable SoundConfiguration getConfiguration() {
|
||||
SoundConfiguration config = Slimefun.getSoundService().getConfiguration(this);
|
||||
|
||||
if (config == null) {
|
||||
// This should not happen. But if it does... send a warning
|
||||
Slimefun.logger().log(Level.WARNING, "Could not find any sound configuration for: {0}", name());
|
||||
}
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will play this {@link SoundEffect} only to the given {@link Player} using the
|
||||
* eye {@link Location} of the {@link Player} and the {@link SoundCategory} {@code PLAYERS}.
|
||||
*
|
||||
* @param player The {@link Player} which to play the {@link Sound} to.
|
||||
*/
|
||||
public void playFor(@Nonnull Player player) {
|
||||
Preconditions.checkNotNull(player, "Cannot play sounds to a Player that is null!");
|
||||
SoundConfiguration config = getConfiguration();
|
||||
|
||||
if (config != null) {
|
||||
Location loc = player.getEyeLocation();
|
||||
player.playSound(loc, config.getSoundId(), SoundCategory.PLAYERS, config.getVolume(), config.getPitch());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will play this {@link SoundEffect} at the given {@link Location} using the
|
||||
* provided {@link SoundCategory}.
|
||||
*
|
||||
* @param loc The {@link Location} at which to play the {@link SoundEffect}.
|
||||
* @param category The {@link SoundCategory} that should be used.
|
||||
*/
|
||||
public void playAt(@Nonnull Location loc, @Nonnull SoundCategory category) {
|
||||
Preconditions.checkNotNull(loc, "The location should not be null.");
|
||||
SoundConfiguration config = getConfiguration();
|
||||
|
||||
if (config != null && loc.getWorld() != null) {
|
||||
loc.getWorld().playSound(loc, config.getSoundId(), category, config.getVolume(), config.getPitch());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will play this {@link SoundEffect} at the {@link Location} of the given {@link Block},
|
||||
* the used {@link SoundCategory} will be {@code BLOCKS}.
|
||||
*
|
||||
* @param block The {@link Block} at which to play the {@link SoundEffect}
|
||||
*/
|
||||
public void playAt(@Nonnull Block block) {
|
||||
Preconditions.checkNotNull(block, "The block cannot be null.");
|
||||
playAt(block.getLocation(), SoundCategory.BLOCKS);
|
||||
}
|
||||
|
||||
/**
|
||||
* This returns the default sound id.
|
||||
*
|
||||
* @return The default sound id.
|
||||
*/
|
||||
public @Nonnull String getDefaultSoundId() {
|
||||
return defaultSound;
|
||||
}
|
||||
|
||||
/**
|
||||
* This returns the default volume.
|
||||
*
|
||||
* @return The default volume.
|
||||
*/
|
||||
public float getDefaultVolume() {
|
||||
return defaultVolume;
|
||||
}
|
||||
|
||||
/**
|
||||
* This returns the default pitch.
|
||||
*
|
||||
* @return The default pitch.
|
||||
*/
|
||||
public float getDefaultPitch() {
|
||||
return defaultPitch;
|
||||
}
|
||||
}
|
@ -0,0 +1,109 @@
|
||||
package io.github.thebusybiscuit.slimefun4.core.services.sounds;
|
||||
|
||||
import java.util.EnumMap;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import io.github.bakedlibs.dough.config.Config;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
/**
|
||||
* The {@link SoundService} is responsible for our sound management.
|
||||
* It allows server owners to fully customize their users' sound experience.
|
||||
*
|
||||
* @author TheBusyBiscuit
|
||||
*/
|
||||
public class SoundService {
|
||||
|
||||
/**
|
||||
* Our {@link Config} instance.
|
||||
*/
|
||||
private final Config config;
|
||||
|
||||
/**
|
||||
* In this map we cache the corresponding {@link SoundConfiguration} to each {@link SoundEffect}.
|
||||
*/
|
||||
private final Map<SoundEffect, SoundConfiguration> soundMap = new EnumMap<>(SoundEffect.class);
|
||||
|
||||
public SoundService(@Nonnull Slimefun plugin) {
|
||||
config = new Config(plugin, "sounds.yml");
|
||||
|
||||
// @formatter:off
|
||||
config.getConfiguration().options().header(
|
||||
"This file is used to assign the sounds which Slimefun will play.\n" +
|
||||
"You can fully customize any sound you want and even change their pitch\n" +
|
||||
"and volume. To disable a sound, simply set the volume to zero.\n"
|
||||
);
|
||||
// @formatter:on
|
||||
|
||||
config.getConfiguration().options().copyHeader();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method reloads every {@link SoundConfiguration}.
|
||||
*
|
||||
* @param save
|
||||
* Whether to save the defaults to disk
|
||||
*/
|
||||
public void reload(boolean save) {
|
||||
config.reload();
|
||||
|
||||
for (SoundEffect sound : SoundEffect.values()) {
|
||||
try {
|
||||
reloadSound(sound);
|
||||
} catch (Exception | LinkageError x) {
|
||||
Slimefun.logger().log(Level.SEVERE, x, () -> "An exception was thrown while trying to load the configuration data for the following sound:" + sound.name());
|
||||
}
|
||||
}
|
||||
|
||||
if (save) {
|
||||
config.save();
|
||||
}
|
||||
}
|
||||
|
||||
private void reloadSound(@Nonnull SoundEffect sound) {
|
||||
// Set up default values
|
||||
config.setDefaultValue(sound.name() + ".sound", sound.getDefaultSoundId());
|
||||
config.setDefaultValue(sound.name() + ".volume", sound.getDefaultVolume());
|
||||
config.setDefaultValue(sound.name() + ".pitch", sound.getDefaultPitch());
|
||||
|
||||
// Read the values
|
||||
String soundId = config.getString(sound.name() + ".sound");
|
||||
float volume = config.getFloat(sound.name() + ".volume");
|
||||
float pitch = config.getFloat(sound.name() + ".pitch");
|
||||
|
||||
// Check whether the volume is at least 0.0
|
||||
if (volume < 0) {
|
||||
Slimefun.logger().log(Level.WARNING, "Invalid value in sounds.yml! Volume for Sound \"{0}\" was {1} (must be at least 0.0)", new Object[] { sound.name(), volume });
|
||||
volume = 0;
|
||||
}
|
||||
|
||||
// Check if the pitch is at least 0.5
|
||||
if (pitch < 0.5F) {
|
||||
Slimefun.logger().log(Level.WARNING, "Invalid value in sounds.yml! Pitch for Sound \"{0}\" was {1} (must be at least 0.5)", new Object[] { sound.name(), pitch });
|
||||
pitch = 0.5F;
|
||||
}
|
||||
|
||||
// Cache this configuration
|
||||
SoundConfiguration configuration = new SoundConfiguration(soundId, volume, pitch);
|
||||
soundMap.put(sound, configuration);
|
||||
}
|
||||
|
||||
/**
|
||||
* This returns the currently used (immutable) {@link SoundConfiguration} for the given {@link SoundEffect}.
|
||||
*
|
||||
* @param sound
|
||||
* The {@link SoundEffect}
|
||||
*
|
||||
* @return The corresponding {@link SoundConfiguration}. This may be null if something went wrong
|
||||
*/
|
||||
public @Nullable SoundConfiguration getConfiguration(@Nonnull SoundEffect sound) {
|
||||
Preconditions.checkNotNull(sound, "The sound must not be null!");
|
||||
return soundMap.get(sound);
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
/**
|
||||
* This package holds classes related to the
|
||||
* {@link io.github.thebusybiscuit.slimefun4.core.services.sounds.SoundService}.
|
||||
* This service is responsible for our sound management and allowing server owners to fully customize
|
||||
* their sound experience.
|
||||
*/
|
||||
package io.github.thebusybiscuit.slimefun4.core.services.sounds;
|
@ -55,6 +55,7 @@ import io.github.thebusybiscuit.slimefun4.core.services.UpdaterService;
|
||||
import io.github.thebusybiscuit.slimefun4.core.services.github.GitHubService;
|
||||
import io.github.thebusybiscuit.slimefun4.core.services.holograms.HologramsService;
|
||||
import io.github.thebusybiscuit.slimefun4.core.services.profiler.SlimefunProfiler;
|
||||
import io.github.thebusybiscuit.slimefun4.core.services.sounds.SoundService;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.items.altar.AncientAltar;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.items.altar.AncientPedestal;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.items.backpacks.Cooler;
|
||||
@ -86,6 +87,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.listeners.MiningAndroid
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.listeners.MultiBlockListener;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.listeners.NetworkListener;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.listeners.PlayerProfileListener;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.listeners.RadioactivityListener;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.listeners.SeismicAxeListener;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.listeners.SlimefunBootsListener;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.listeners.SlimefunBowListener;
|
||||
@ -114,7 +116,10 @@ import io.github.thebusybiscuit.slimefun4.implementation.resources.GEOResourcesS
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.setup.PostSetup;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.setup.ResearchSetup;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.setup.SlimefunItemSetup;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.tasks.ArmorTask;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.tasks.armor.RadiationTask;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.tasks.armor.RainbowArmorTask;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.tasks.armor.SlimefunArmorTask;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.tasks.armor.SolarHelmetTask;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.tasks.SlimefunStartupTask;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.tasks.TickerTask;
|
||||
import io.github.thebusybiscuit.slimefun4.integrations.IntegrationsManager;
|
||||
@ -175,6 +180,7 @@ public final class Slimefun extends JavaPlugin implements SlimefunAddon {
|
||||
private final PerWorldSettingsService worldSettingsService = new PerWorldSettingsService(this);
|
||||
private final MinecraftRecipeService recipeService = new MinecraftRecipeService(this);
|
||||
private final HologramsService hologramsService = new HologramsService(this);
|
||||
private final SoundService soundService = new SoundService(this);
|
||||
|
||||
// Some other things we need
|
||||
private final IntegrationsManager integrations = new IntegrationsManager(this);
|
||||
@ -250,6 +256,7 @@ public final class Slimefun extends JavaPlugin implements SlimefunAddon {
|
||||
command.register();
|
||||
registry.load(this, config);
|
||||
loadTags();
|
||||
soundService.reload(false);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -338,6 +345,7 @@ public final class Slimefun extends JavaPlugin implements SlimefunAddon {
|
||||
runSync(new SlimefunStartupTask(this, () -> {
|
||||
textureService.register(registry.getAllSlimefunItems(), true);
|
||||
permissionsService.register(registry.getAllSlimefunItems(), true);
|
||||
soundService.reload(true);
|
||||
|
||||
// This try/catch should prevent buggy Spigot builds from blocking item loading
|
||||
try {
|
||||
@ -357,8 +365,10 @@ public final class Slimefun extends JavaPlugin implements SlimefunAddon {
|
||||
|
||||
// Armor Update Task
|
||||
if (config.getBoolean("options.enable-armor-effects")) {
|
||||
boolean radioactiveFire = config.getBoolean("options.burn-players-when-radioactive");
|
||||
getServer().getScheduler().runTaskTimerAsynchronously(this, new ArmorTask(radioactiveFire), 0L, config.getInt("options.armor-update-interval") * 20L);
|
||||
new SlimefunArmorTask().schedule(this, config.getInt("options.armor-update-interval") * 20L);
|
||||
new RadiationTask().schedule(this, config.getInt("options.radiation-update-interval") * 20L);
|
||||
new RainbowArmorTask().schedule(this, config.getInt("options.rainbow-armor-update-interval") * 20L);
|
||||
new SolarHelmetTask().schedule(this, config.getInt("options.armor-update-interval"));
|
||||
}
|
||||
|
||||
// Starting our tasks
|
||||
@ -640,6 +650,7 @@ public final class Slimefun extends JavaPlugin implements SlimefunAddon {
|
||||
// Item-specific Listeners
|
||||
new CoolerListener(this, (Cooler) SlimefunItems.COOLER.getItem());
|
||||
new SeismicAxeListener(this, (SeismicAxe) SlimefunItems.SEISMIC_AXE.getItem());
|
||||
new RadioactivityListener(this);
|
||||
new AncientAltarListener(this, (AncientAltar) SlimefunItems.ANCIENT_ALTAR.getItem(), (AncientPedestal) SlimefunItems.ANCIENT_PEDESTAL.getItem());
|
||||
grapplingHookListener.register(this, (GrapplingHook) SlimefunItems.GRAPPLING_HOOK.getItem());
|
||||
bowListener.register(this);
|
||||
@ -833,6 +844,17 @@ public final class Slimefun extends JavaPlugin implements SlimefunAddon {
|
||||
return instance.hologramsService;
|
||||
}
|
||||
|
||||
/**
|
||||
* This returns our {@link SoundService} which handles the configuration of all sounds used in Slimefun
|
||||
*
|
||||
* @return Our instance of {@link SoundService}
|
||||
*/
|
||||
@Nonnull
|
||||
public static SoundService getSoundService() {
|
||||
validateInstance();
|
||||
return instance.soundService;
|
||||
}
|
||||
|
||||
/**
|
||||
* This returns our instance of {@link IntegrationsManager}.
|
||||
* This is responsible for managing any integrations with third party {@link Plugin plugins}.
|
||||
|
@ -221,7 +221,11 @@ public final class SlimefunItems {
|
||||
public static final SlimefunItemStack GLOWSTONE_CHESTPLATE = new SlimefunItemStack("GLOWSTONE_CHESTPLATE", Material.LEATHER_CHESTPLATE, Color.YELLOW, "&e&lGlowstone Chestplate", "", "&a&oShining like the sun!", "", "&9+ Night Vision");
|
||||
public static final SlimefunItemStack GLOWSTONE_LEGGINGS = new SlimefunItemStack("GLOWSTONE_LEGGINGS", Material.LEATHER_LEGGINGS, Color.YELLOW, "&e&lGlowstone Leggings", "", "&a&oShining like the sun!", "", "&9+ Night Vision");
|
||||
public static final SlimefunItemStack GLOWSTONE_BOOTS = new SlimefunItemStack("GLOWSTONE_BOOTS", Material.LEATHER_BOOTS, Color.YELLOW, "&e&lGlowstone Boots", "", "&a&oShining like the sun!", "", "&9+ Night Vision");
|
||||
|
||||
public static final SlimefunItemStack RAINBOW_LEATHER = new SlimefunItemStack("RAINBOW_LEATHER", Material.RABBIT_HIDE, Color.FUCHSIA, "&dRainbow Leather", "", "&fCan be used to craft rainbow armor");
|
||||
public static final SlimefunItemStack RAINBOW_HELMET = new SlimefunItemStack("RAINBOW_HELMET", Material.LEATHER_HELMET, Color.FUCHSIA, "&d&lRainbow Helmet", "", LoreBuilder.RAINBOW);
|
||||
public static final SlimefunItemStack RAINBOW_CHESTPLATE = new SlimefunItemStack("RAINBOW_CHESTPLATE", Material.LEATHER_CHESTPLATE, Color.FUCHSIA, "&d&lRainbow Chestplate", "", LoreBuilder.RAINBOW);
|
||||
public static final SlimefunItemStack RAINBOW_LEGGINGS = new SlimefunItemStack("RAINBOW_LEGGINGS", Material.LEATHER_LEGGINGS, Color.FUCHSIA, "&d&lRainbow Leggings", "", LoreBuilder.RAINBOW);
|
||||
public static final SlimefunItemStack RAINBOW_BOOTS = new SlimefunItemStack("RAINBOW_BOOTS", Material.LEATHER_BOOTS, Color.FUCHSIA, "&d&lRainbow Boots", "", LoreBuilder.RAINBOW);
|
||||
public static final SlimefunItemStack ENDER_HELMET = new SlimefunItemStack("ENDER_HELMET", Material.LEATHER_HELMET, Color.fromRGB(28, 25, 112), "&5&lEnder Helmet", "", "&a&oSometimes its here, sometimes there!");
|
||||
public static final SlimefunItemStack ENDER_CHESTPLATE = new SlimefunItemStack("ENDER_CHESTPLATE", Material.LEATHER_CHESTPLATE, Color.fromRGB(28, 25, 112), "&5&lEnder Chestplate", "", "&a&oSometimes its here, sometimes there!");
|
||||
public static final SlimefunItemStack ENDER_LEGGINGS = new SlimefunItemStack("ENDER_LEGGINGS", Material.LEATHER_LEGGINGS, Color.fromRGB(28, 25, 112), "&5&lEnder Leggings", "", "&a&oSometimes its here, sometimes there!");
|
||||
@ -419,14 +423,12 @@ public final class SlimefunItems {
|
||||
public static final SlimefunItemStack CRAFTING_MOTOR = new SlimefunItemStack("CRAFTING_MOTOR", HeadTexture.CRAFTING_MOTOR, "&6Crafting Motor", "", "&7Important component of Auto-Crafters");
|
||||
|
||||
/* Rainbow blocks */
|
||||
private static final String RAINBOW = "&dCycles through all Colors of the Rainbow!";
|
||||
public static final SlimefunItemStack RAINBOW_WOOL = new SlimefunItemStack("RAINBOW_WOOL", Material.WHITE_WOOL, "&5Rainbow Wool", "", RAINBOW);
|
||||
public static final SlimefunItemStack RAINBOW_GLASS = new SlimefunItemStack("RAINBOW_GLASS", Material.WHITE_STAINED_GLASS, "&5Rainbow Glass", "", RAINBOW);
|
||||
public static final SlimefunItemStack RAINBOW_CLAY = new SlimefunItemStack("RAINBOW_CLAY", Material.WHITE_TERRACOTTA, "&5Rainbow Clay", "", RAINBOW);
|
||||
public static final SlimefunItemStack RAINBOW_GLASS_PANE = new SlimefunItemStack("RAINBOW_GLASS_PANE", Material.WHITE_STAINED_GLASS_PANE, "&5Rainbow Glass Pane", "", RAINBOW);
|
||||
public static final SlimefunItemStack RAINBOW_CONCRETE = new SlimefunItemStack("RAINBOW_CONCRETE", Material.WHITE_CONCRETE, "&5Rainbow Concrete", "", RAINBOW);
|
||||
public static final SlimefunItemStack RAINBOW_GLAZED_TERRACOTTA = new SlimefunItemStack("RAINBOW_GLAZED_TERRACOTTA", Material.WHITE_GLAZED_TERRACOTTA, "&5Rainbow Glazed Terracotta", "", RAINBOW);
|
||||
|
||||
public static final SlimefunItemStack RAINBOW_WOOL = new SlimefunItemStack("RAINBOW_WOOL", Material.WHITE_WOOL, "&5Rainbow Wool", "", LoreBuilder.RAINBOW);
|
||||
public static final SlimefunItemStack RAINBOW_GLASS = new SlimefunItemStack("RAINBOW_GLASS", Material.WHITE_STAINED_GLASS, "&5Rainbow Glass", "", LoreBuilder.RAINBOW);
|
||||
public static final SlimefunItemStack RAINBOW_CLAY = new SlimefunItemStack("RAINBOW_CLAY", Material.WHITE_TERRACOTTA, "&5Rainbow Clay", "", LoreBuilder.RAINBOW);
|
||||
public static final SlimefunItemStack RAINBOW_GLASS_PANE = new SlimefunItemStack("RAINBOW_GLASS_PANE", Material.WHITE_STAINED_GLASS_PANE, "&5Rainbow Glass Pane", "", LoreBuilder.RAINBOW);
|
||||
public static final SlimefunItemStack RAINBOW_CONCRETE = new SlimefunItemStack("RAINBOW_CONCRETE", Material.WHITE_CONCRETE, "&5Rainbow Concrete", "", LoreBuilder.RAINBOW);
|
||||
public static final SlimefunItemStack RAINBOW_GLAZED_TERRACOTTA = new SlimefunItemStack("RAINBOW_GLAZED_TERRACOTTA", Material.WHITE_GLAZED_TERRACOTTA, "&5Rainbow Glazed Terracotta", "", LoreBuilder.RAINBOW);
|
||||
/* Seasonal */
|
||||
private static final String CHRISTMAS = ChatUtils.christmas("[Christmas Edition]");
|
||||
public static final SlimefunItemStack RAINBOW_WOOL_XMAS = new SlimefunItemStack("RAINBOW_WOOL_XMAS", Material.WHITE_WOOL, "&5Rainbow Wool &7(Christmas)", "", CHRISTMAS);
|
||||
|
@ -14,7 +14,6 @@ import javax.annotation.ParametersAreNonnullByDefault;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.Tag;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
@ -44,6 +43,7 @@ import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideMode;
|
||||
import io.github.thebusybiscuit.slimefun4.core.guide.options.SlimefunGuideSettings;
|
||||
import io.github.thebusybiscuit.slimefun4.core.multiblocks.MultiBlock;
|
||||
import io.github.thebusybiscuit.slimefun4.core.multiblocks.MultiBlockMachine;
|
||||
import io.github.thebusybiscuit.slimefun4.core.services.sounds.SoundEffect;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.tasks.AsyncRecipeChoiceTask;
|
||||
import io.github.thebusybiscuit.slimefun4.utils.ChatUtils;
|
||||
@ -67,7 +67,6 @@ import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu.MenuClickHan
|
||||
public class SurvivalSlimefunGuide implements SlimefunGuideImplementation {
|
||||
|
||||
private static final int MAX_ITEM_GROUPS = 36;
|
||||
private static final Sound sound = Sound.ITEM_BOOK_PAGE_TURN;
|
||||
|
||||
private final int[] recipeSlots = { 3, 4, 5, 12, 13, 14, 21, 22, 23 };
|
||||
private final ItemStack item;
|
||||
@ -80,16 +79,6 @@ public class SurvivalSlimefunGuide implements SlimefunGuideImplementation {
|
||||
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}
|
||||
*/
|
||||
public @Nonnull Sound getSound() {
|
||||
return sound;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nonnull SlimefunGuideMode getMode() {
|
||||
return SlimefunGuideMode.SURVIVAL_MODE;
|
||||
@ -683,7 +672,7 @@ public class SurvivalSlimefunGuide implements SlimefunGuideImplementation {
|
||||
menu.addMenuClickHandler(28, (pl, slot, itemstack, action) -> {
|
||||
if (page > 0) {
|
||||
displayRecipes(pl, profile, menu, sfItem, page - 1);
|
||||
pl.playSound(pl.getLocation(), sound, 1, 1);
|
||||
SoundEffect.GUIDE_BUTTON_CLICK_SOUND.playFor(pl);
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -693,7 +682,7 @@ public class SurvivalSlimefunGuide implements SlimefunGuideImplementation {
|
||||
menu.addMenuClickHandler(34, (pl, slot, itemstack, action) -> {
|
||||
if (recipes.size() > (18 * (page + 1))) {
|
||||
displayRecipes(pl, profile, menu, sfItem, page + 1);
|
||||
pl.playSound(pl.getLocation(), sound, 1, 1);
|
||||
SoundEffect.GUIDE_BUTTON_CLICK_SOUND.playFor(pl);
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -753,7 +742,7 @@ public class SurvivalSlimefunGuide implements SlimefunGuideImplementation {
|
||||
ChestMenu menu = new ChestMenu(Slimefun.getLocalization().getMessage(p, "guide.title.main"));
|
||||
|
||||
menu.setEmptySlotsClickable(false);
|
||||
menu.addMenuOpeningHandler(pl -> pl.playSound(pl.getLocation(), sound, 1, 1));
|
||||
menu.addMenuOpeningHandler(SoundEffect.GUIDE_BUTTON_CLICK_SOUND::playFor);
|
||||
return menu;
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,30 @@
|
||||
package io.github.thebusybiscuit.slimefun4.implementation.items;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup;
|
||||
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem;
|
||||
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
|
||||
import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
|
||||
import io.github.thebusybiscuit.slimefun4.core.handlers.ItemUseHandler;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
|
||||
|
||||
/**
|
||||
* The {@link EnchantedItem} is an enchanted {@link SlimefunItem}.
|
||||
* By default, this class sets items to be not disenchantable.
|
||||
*
|
||||
* @author Fury_Phoenix
|
||||
*
|
||||
*/
|
||||
public class EnchantedItem extends SlimefunItem {
|
||||
|
||||
@ParametersAreNonnullByDefault
|
||||
public EnchantedItem(ItemGroup itemGroup, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
||||
super(itemGroup, item, recipeType, recipe);
|
||||
disenchantable = false;
|
||||
}
|
||||
|
||||
}
|
@ -9,7 +9,6 @@ import javax.annotation.ParametersAreNonnullByDefault;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
@ -22,6 +21,7 @@ import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup;
|
||||
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
|
||||
import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
|
||||
import io.github.thebusybiscuit.slimefun4.core.handlers.ItemUseHandler;
|
||||
import io.github.thebusybiscuit.slimefun4.core.services.sounds.SoundEffect;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.items.magical.staves.StormStaff;
|
||||
import io.github.thebusybiscuit.slimefun4.utils.LoreBuilder;
|
||||
@ -116,7 +116,7 @@ public abstract class LimitedUseItem extends SimpleSlimefunItem<ItemUseHandler>
|
||||
int usesLeft = pdc.getOrDefault(key, PersistentDataType.INTEGER, getMaxUseCount());
|
||||
|
||||
if (usesLeft == 1) {
|
||||
p.playSound(p.getLocation(), Sound.ENTITY_ITEM_BREAK, 1, 1);
|
||||
SoundEffect.LIMITED_USE_ITEM_BREAK_SOUND.playFor(p);
|
||||
item.setAmount(0);
|
||||
item.setType(Material.AIR);
|
||||
} else {
|
||||
|
@ -8,8 +8,8 @@ import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.ArmorStand;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Item;
|
||||
import org.bukkit.entity.Player;
|
||||
@ -24,13 +24,16 @@ import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup;
|
||||
import io.github.thebusybiscuit.slimefun4.api.items.ItemSpawnReason;
|
||||
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
|
||||
import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
|
||||
import io.github.thebusybiscuit.slimefun4.core.attributes.NotHopperable;
|
||||
import io.github.thebusybiscuit.slimefun4.core.handlers.BlockBreakHandler;
|
||||
import io.github.thebusybiscuit.slimefun4.core.handlers.BlockDispenseHandler;
|
||||
import io.github.thebusybiscuit.slimefun4.core.services.sounds.SoundEffect;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.handlers.SimpleBlockBreakHandler;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.listeners.AncientAltarListener;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.tasks.AncientAltarTask;
|
||||
import io.github.thebusybiscuit.slimefun4.utils.ArmorStandUtils;
|
||||
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
|
||||
|
||||
/**
|
||||
@ -40,13 +43,14 @@ import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
|
||||
*
|
||||
* @author Redemption198
|
||||
* @author TheBusyBiscuit
|
||||
* @author JustAHuman
|
||||
*
|
||||
* @see AncientAltar
|
||||
* @see AncientAltarListener
|
||||
* @see AncientAltarTask
|
||||
*
|
||||
*/
|
||||
public class AncientPedestal extends SimpleSlimefunItem<BlockDispenseHandler> {
|
||||
public class AncientPedestal extends SimpleSlimefunItem<BlockDispenseHandler> implements NotHopperable {
|
||||
|
||||
public static final String ITEM_PREFIX = ChatColors.color("&dALTAR &3Probe - &e");
|
||||
|
||||
@ -63,6 +67,7 @@ public class AncientPedestal extends SimpleSlimefunItem<BlockDispenseHandler> {
|
||||
@Override
|
||||
public void onBlockBreak(@Nonnull Block b) {
|
||||
Optional<Item> entity = getPlacedItem(b);
|
||||
ArmorStand armorStand = getArmorStand(b, false);
|
||||
|
||||
if (entity.isPresent()) {
|
||||
Item stack = entity.get();
|
||||
@ -73,6 +78,10 @@ public class AncientPedestal extends SimpleSlimefunItem<BlockDispenseHandler> {
|
||||
stack.remove();
|
||||
}
|
||||
}
|
||||
|
||||
if (armorStand != null && armorStand.isValid()) {
|
||||
armorStand.remove();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -85,7 +94,7 @@ public class AncientPedestal extends SimpleSlimefunItem<BlockDispenseHandler> {
|
||||
public @Nonnull Optional<Item> getPlacedItem(@Nonnull Block pedestal) {
|
||||
Location l = pedestal.getLocation().add(0.5, 1.2, 0.5);
|
||||
|
||||
for (Entity n : l.getWorld().getNearbyEntities(l, 0.5, 0.5, 0.5, this::testItem)) {
|
||||
for (Entity n : l.getWorld().getNearbyEntities(l, 0.5, 0.5, 0.5, AncientPedestal::testItem)) {
|
||||
if (n instanceof Item item) {
|
||||
return Optional.of(item);
|
||||
}
|
||||
@ -94,7 +103,24 @@ public class AncientPedestal extends SimpleSlimefunItem<BlockDispenseHandler> {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
private boolean testItem(@Nullable Entity n) {
|
||||
public @Nullable ArmorStand getArmorStand(@Nonnull Block pedestal, boolean createIfNoneExists) {
|
||||
Optional<Item> entity = getPlacedItem(pedestal);
|
||||
|
||||
if (entity.isPresent() && entity.get().getVehicle() instanceof ArmorStand armorStand) {
|
||||
return armorStand;
|
||||
}
|
||||
|
||||
Location l = pedestal.getLocation().add(0.5, 1.2, 0.5);
|
||||
for (Entity n : l.getWorld().getNearbyEntities(l, 0.5, 0.5, 0.5, this::testArmorStand)) {
|
||||
if (n instanceof ArmorStand armorStand) {
|
||||
return armorStand;
|
||||
}
|
||||
}
|
||||
|
||||
return createIfNoneExists ? ArmorStandUtils.spawnArmorStand(l) : null;
|
||||
}
|
||||
|
||||
public static boolean testItem(@Nullable Entity n) {
|
||||
if (n instanceof Item item && n.isValid()) {
|
||||
ItemMeta meta = item.getItemStack().getItemMeta();
|
||||
|
||||
@ -104,16 +130,23 @@ public class AncientPedestal extends SimpleSlimefunItem<BlockDispenseHandler> {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean testArmorStand(@Nullable Entity n) {
|
||||
if (n instanceof ArmorStand && n.isValid()) {
|
||||
String customName = n.getCustomName();
|
||||
return customName != null && customName.startsWith(ITEM_PREFIX);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public @Nonnull ItemStack getOriginalItemStack(@Nonnull Item item) {
|
||||
ItemStack stack = item.getItemStack().clone();
|
||||
String customName = item.getCustomName();
|
||||
|
||||
if (customName.equals(ItemUtils.getItemName(new ItemStack(stack.getType())))) {
|
||||
ItemMeta im = stack.getItemMeta();
|
||||
String customName = item.getCustomName();
|
||||
im.setDisplayName(null);
|
||||
stack.setItemMeta(im);
|
||||
} else {
|
||||
ItemMeta im = stack.getItemMeta();
|
||||
|
||||
if (customName == null || !customName.equals(ItemUtils.getItemName(stack))) {
|
||||
im.setDisplayName(customName);
|
||||
stack.setItemMeta(im);
|
||||
}
|
||||
@ -123,7 +156,8 @@ public class AncientPedestal extends SimpleSlimefunItem<BlockDispenseHandler> {
|
||||
|
||||
public void placeItem(@Nonnull Player p, @Nonnull Block b) {
|
||||
ItemStack hand = p.getInventory().getItemInMainHand();
|
||||
ItemStack displayItem = new CustomItemStack(hand, ITEM_PREFIX + System.nanoTime());
|
||||
String displayName = ITEM_PREFIX + System.nanoTime();
|
||||
ItemStack displayItem = new CustomItemStack(hand, displayName);
|
||||
displayItem.setAmount(1);
|
||||
|
||||
// Get the display name of the original Item in the Player's hand
|
||||
@ -136,11 +170,15 @@ public class AncientPedestal extends SimpleSlimefunItem<BlockDispenseHandler> {
|
||||
Item entity = SlimefunUtils.spawnItem(b.getLocation().add(0.5, 1.2, 0.5), displayItem, ItemSpawnReason.ANCIENT_PEDESTAL_PLACE_ITEM);
|
||||
|
||||
if (entity != null) {
|
||||
ArmorStand armorStand = getArmorStand(b, true);
|
||||
entity.setInvulnerable(true);
|
||||
entity.setVelocity(new Vector(0, 0.1, 0));
|
||||
entity.setCustomNameVisible(true);
|
||||
entity.setCustomName(nametag);
|
||||
armorStand.setCustomName(displayName);
|
||||
armorStand.addPassenger(entity);
|
||||
SlimefunUtils.markAsNoPickup(entity, "altar_item");
|
||||
p.playSound(b.getLocation(), Sound.ENTITY_ITEM_PICKUP, 0.3F, 0.3F);
|
||||
SoundEffect.ANCIENT_PEDESTAL_ITEM_PLACE_SOUND.playAt(b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ public enum AndroidType {
|
||||
FIGHTER,
|
||||
|
||||
/**
|
||||
* The {@link FisherAndroid} can catch a fish and other materials.
|
||||
* The {@link FishermanAndroid} can catch a fish and other materials.
|
||||
*/
|
||||
FISHERMAN,
|
||||
|
||||
|
@ -2,8 +2,9 @@ package io.github.thebusybiscuit.slimefun4.implementation.items.androids;
|
||||
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.Tag;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
@ -13,14 +14,16 @@ import io.github.bakedlibs.dough.collections.RandomizedSet;
|
||||
import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup;
|
||||
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
|
||||
import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
|
||||
import io.github.thebusybiscuit.slimefun4.core.services.sounds.SoundEffect;
|
||||
|
||||
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu;
|
||||
|
||||
public class FisherAndroid extends ProgrammableAndroid {
|
||||
public class FishermanAndroid extends ProgrammableAndroid {
|
||||
|
||||
private final RandomizedSet<ItemStack> fishingLoot = new RandomizedSet<>();
|
||||
|
||||
public FisherAndroid(ItemGroup itemGroup, int tier, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
||||
@ParametersAreNonnullByDefault
|
||||
public FishermanAndroid(ItemGroup itemGroup, int tier, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
||||
super(itemGroup, tier, item, recipeType, recipe);
|
||||
|
||||
// Fish
|
||||
@ -54,14 +57,12 @@ public class FisherAndroid extends ProgrammableAndroid {
|
||||
Block water = b.getRelative(BlockFace.DOWN);
|
||||
|
||||
if (water.getType() == Material.WATER) {
|
||||
water.getWorld().playSound(water.getLocation(), Sound.ENTITY_PLAYER_SPLASH, 0.3F, 0.7F);
|
||||
SoundEffect.FISHERMAN_ANDROID_FISHING_SOUND.playAt(water);
|
||||
|
||||
if (ThreadLocalRandom.current().nextInt(100) < 10 * getTier()) {
|
||||
ItemStack drop = fishingLoot.getRandom();
|
||||
menu.pushItem(drop.clone(), getOutputSlots());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -182,7 +182,7 @@ public enum Instruction {
|
||||
CHOP_TREE(AndroidType.WOODCUTTER, HeadTexture.SCRIPT_CHOP_TREE),
|
||||
|
||||
/**
|
||||
* This {@link Instruction} makes a {@link FisherAndroid} try to catch fish from
|
||||
* This {@link Instruction} makes a {@link FishermanAndroid} try to catch fish from
|
||||
* the water below.
|
||||
*/
|
||||
CATCH_FISH(AndroidType.FISHERMAN, HeadTexture.SCRIPT_FISH, (android, b, inv, face) -> android.fish(b, inv)),
|
||||
|
@ -11,7 +11,6 @@ import org.bukkit.Effect;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.Particle;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
@ -22,6 +21,7 @@ import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup;
|
||||
import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting;
|
||||
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
|
||||
import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
|
||||
import io.github.thebusybiscuit.slimefun4.core.services.sounds.SoundEffect;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
|
||||
import io.github.thebusybiscuit.slimefun4.utils.InfiniteBlockGenerator;
|
||||
import io.github.thebusybiscuit.slimefun4.utils.tags.SlimefunTag;
|
||||
@ -148,7 +148,7 @@ public class MinerAndroid extends ProgrammableAndroid {
|
||||
}
|
||||
|
||||
// "poof" a "new" block was generated
|
||||
block.getWorld().playSound(block.getLocation(), Sound.BLOCK_FIRE_EXTINGUISH, 0.075F, 0.8F);
|
||||
SoundEffect.MINER_ANDROID_BLOCK_GENERATION_SOUND.playAt(block);
|
||||
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);
|
||||
|
@ -14,7 +14,6 @@ import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.Tag;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
@ -45,6 +44,7 @@ import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
|
||||
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.services.sounds.SoundEffect;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
|
||||
import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils;
|
||||
@ -373,7 +373,7 @@ public class ProgrammableAndroid extends SlimefunItem implements InventoryBlock,
|
||||
ChestMenu menu = new ChestMenu("Android Scripts");
|
||||
|
||||
menu.setEmptySlotsClickable(false);
|
||||
menu.addMenuOpeningHandler(pl -> pl.playSound(pl.getLocation(), Sound.BLOCK_NOTE_BLOCK_HAT, 0.7F, 0.7F));
|
||||
menu.addMenuOpeningHandler(SoundEffect.PROGRAMMABLE_ANDROID_SCRIPT_DOWNLOAD_SOUND::playFor);
|
||||
|
||||
List<Script> scripts = Script.getUploadedScripts(getAndroidType());
|
||||
int pages = (scripts.size() / 45) + 1;
|
||||
@ -895,7 +895,11 @@ public class ProgrammableAndroid extends SlimefunItem implements InventoryBlock,
|
||||
|
||||
Slimefun.runSync(() -> {
|
||||
PlayerSkin skin = PlayerSkin.fromBase64(texture);
|
||||
Material type = block.getType();
|
||||
// Ensure that this Block is still a Player Head
|
||||
if (type == Material.PLAYER_HEAD || type == Material.PLAYER_WALL_HEAD) {
|
||||
PlayerHead.setSkin(block, skin, true);
|
||||
}
|
||||
});
|
||||
|
||||
b.setType(Material.AIR);
|
||||
|
@ -162,6 +162,17 @@ public class WoodcutterAndroid extends ProgrammableAndroid {
|
||||
}
|
||||
}
|
||||
|
||||
if (Slimefun.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_20)) {
|
||||
switch (logType) {
|
||||
case CHERRY_LOG,
|
||||
STRIPPED_CHERRY_LOG -> {
|
||||
saplingType = Material.CHERRY_SAPLING;
|
||||
soilRequirement = SlimefunTag.DIRT_VARIANTS::isTagged;
|
||||
}
|
||||
default -> {}
|
||||
}
|
||||
}
|
||||
|
||||
if (saplingType != null && soilRequirement != null) {
|
||||
if (soilRequirement.test(block.getRelative(BlockFace.DOWN).getType())) {
|
||||
// Replant the block
|
||||
|
@ -1,5 +1,6 @@
|
||||
package io.github.thebusybiscuit.slimefun4.implementation.items.armor;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
@ -8,11 +9,12 @@ import org.bukkit.potion.PotionEffect;
|
||||
import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup;
|
||||
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
|
||||
import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
|
||||
import io.github.thebusybiscuit.slimefun4.core.services.sounds.SoundEffect;
|
||||
|
||||
/**
|
||||
* {@link LongFallBoots} are a pair of boots which negate fall damage.
|
||||
* Nameworthy examples of this are Slime Boots and Bee Boots.
|
||||
*
|
||||
* <p>
|
||||
* <i>Yes, you just found a Portal reference :P</i>
|
||||
*
|
||||
* @author TheBusyBiscuit
|
||||
@ -20,9 +22,31 @@ import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
|
||||
*/
|
||||
public class LongFallBoots extends SlimefunArmorPiece {
|
||||
|
||||
private final SoundEffect soundEffect;
|
||||
|
||||
/**
|
||||
* @deprecated In RC-35, marked for removal in RC-36
|
||||
*/
|
||||
@Deprecated
|
||||
@ParametersAreNonnullByDefault
|
||||
public LongFallBoots(ItemGroup itemGroup, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe, PotionEffect[] effects) {
|
||||
super(itemGroup, item, recipeType, recipe, effects);
|
||||
this(itemGroup, item, recipeType, recipe, effects, SoundEffect.SLIME_BOOTS_FALL_SOUND);
|
||||
}
|
||||
|
||||
@ParametersAreNonnullByDefault
|
||||
public LongFallBoots(ItemGroup itemGroup, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe, PotionEffect[] effects, SoundEffect soundEffect) {
|
||||
super(itemGroup, item, recipeType, recipe, effects);
|
||||
|
||||
this.soundEffect = soundEffect;
|
||||
}
|
||||
|
||||
/**
|
||||
* This returns the {@link SoundEffect} that is played upon landing with these boots.
|
||||
*
|
||||
* @return The {@link SoundEffect} played when landing
|
||||
*/
|
||||
@Nonnull
|
||||
public SoundEffect getSoundEffect() {
|
||||
return soundEffect;
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem;
|
||||
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
|
||||
import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.gadgets.Jetpack;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.tasks.ParachuteTask;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.tasks.player.ParachuteTask;
|
||||
|
||||
/**
|
||||
* The {@link Parachute} is a {@link SlimefunItem} that can be equipped as a chestplate.
|
||||
|
@ -0,0 +1,62 @@
|
||||
package io.github.thebusybiscuit.slimefun4.implementation.items.armor;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.Color;
|
||||
import org.bukkit.DyeColor;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
|
||||
import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup;
|
||||
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
|
||||
import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
|
||||
import io.github.thebusybiscuit.slimefun4.utils.tags.SlimefunTag;
|
||||
|
||||
/**
|
||||
* Represents a {@link SlimefunArmorPiece} with rainbow properties (leather armor changing color).
|
||||
*
|
||||
* @author martinbrom
|
||||
*/
|
||||
public class RainbowArmorPiece extends SlimefunArmorPiece {
|
||||
|
||||
private final Color[] colors;
|
||||
|
||||
/**
|
||||
* This creates a new {@link RainbowArmorPiece} from the given arguments.
|
||||
*
|
||||
* @param itemGroup The {@link ItemGroup} this {@link RainbowArmorPiece} belongs to
|
||||
* @param item The {@link SlimefunItemStack} that describes the visual features of our {@link RainbowArmorPiece}
|
||||
* @param recipeType the {@link RecipeType} that determines how this {@link RainbowArmorPiece} is crafted
|
||||
* @param recipe An Array representing the recipe of this {@link RainbowArmorPiece}
|
||||
* @param dyeColors An Array representing the {@link DyeColor}s this {@link RainbowArmorPiece} will cycle between
|
||||
*/
|
||||
@ParametersAreNonnullByDefault
|
||||
public RainbowArmorPiece(ItemGroup itemGroup, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe, DyeColor[] dyeColors) {
|
||||
super(itemGroup, item, recipeType, recipe, new PotionEffect[0]);
|
||||
|
||||
// TODO Change this validation over to our custom validation blocked by https://github.com/baked-libs/dough/pull/184
|
||||
Validate.notEmpty(dyeColors, "RainbowArmorPiece colors cannot be empty!");
|
||||
|
||||
if (!SlimefunTag.LEATHER_ARMOR.isTagged(item.getType())) {
|
||||
throw new IllegalArgumentException("Rainbow armor needs to be a leather armor piece!");
|
||||
}
|
||||
|
||||
colors = Arrays.stream(dyeColors)
|
||||
.map(DyeColor::getColor)
|
||||
.toArray(Color[]::new);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link Color}s this {@link RainbowArmorPiece} cycles between
|
||||
*
|
||||
* @return The {@link Color}s of this {@link RainbowArmorPiece}
|
||||
*/
|
||||
public @Nonnull Color[] getColors() {
|
||||
return colors;
|
||||
}
|
||||
|
||||
}
|
@ -6,7 +6,6 @@ import javax.annotation.ParametersAreNonnullByDefault;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Effect;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.entity.Entity;
|
||||
@ -23,6 +22,7 @@ import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup;
|
||||
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem;
|
||||
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
|
||||
import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
|
||||
import io.github.thebusybiscuit.slimefun4.core.services.sounds.SoundEffect;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
|
||||
|
||||
/**
|
||||
@ -47,7 +47,7 @@ public class StomperBoots extends SlimefunItem {
|
||||
*/
|
||||
public void stomp(@Nonnull EntityDamageEvent fallDamageEvent) {
|
||||
Player player = (Player) fallDamageEvent.getEntity();
|
||||
player.getWorld().playSound(player.getLocation(), Sound.ENTITY_ZOMBIE_BREAK_WOODEN_DOOR, 1F, 2F);
|
||||
SoundEffect.STOMPER_BOOTS_STOMP_SOUND.playFor(player);
|
||||
player.setVelocity(new Vector(0, 0.7, 0));
|
||||
|
||||
for (Entity entity : player.getNearbyEntities(4, 4, 4)) {
|
||||
|
@ -15,7 +15,6 @@ import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.Particle;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.BlockState;
|
||||
@ -36,6 +35,7 @@ import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
|
||||
import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
|
||||
import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetComponent;
|
||||
import io.github.thebusybiscuit.slimefun4.core.networks.energy.EnergyNetComponentType;
|
||||
import io.github.thebusybiscuit.slimefun4.core.services.sounds.SoundEffect;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.listeners.AutoCrafterListener;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.tasks.AsyncRecipeChoiceTask;
|
||||
@ -314,7 +314,7 @@ public abstract class AbstractAutoCrafter extends SlimefunItem implements Energy
|
||||
recipe.show(menu, task);
|
||||
menu.open(p);
|
||||
|
||||
p.playSound(p.getLocation(), Sound.UI_BUTTON_CLICK, 1, 1);
|
||||
SoundEffect.AUTO_CRAFTER_GUI_CLICK_SOUND.playFor(p);
|
||||
|
||||
// Only schedule the task if necessary
|
||||
if (!task.isEmpty()) {
|
||||
@ -325,7 +325,7 @@ public abstract class AbstractAutoCrafter extends SlimefunItem implements Energy
|
||||
@ParametersAreNonnullByDefault
|
||||
private void setRecipeEnabled(Player p, Block b, boolean enabled) {
|
||||
p.closeInventory();
|
||||
p.playSound(p.getLocation(), Sound.UI_BUTTON_CLICK, 1, 1);
|
||||
SoundEffect.AUTO_CRAFTER_GUI_CLICK_SOUND.playFor(p);
|
||||
BlockState state = PaperLib.getBlockState(b, false).getState();
|
||||
|
||||
// Make sure the block is still a Skull
|
||||
@ -344,7 +344,7 @@ public abstract class AbstractAutoCrafter extends SlimefunItem implements Energy
|
||||
private void deleteRecipe(Player p, Block b) {
|
||||
setSelectedRecipe(b, null);
|
||||
p.closeInventory();
|
||||
p.playSound(p.getLocation(), Sound.UI_BUTTON_CLICK, 1, 1);
|
||||
SoundEffect.AUTO_CRAFTER_GUI_CLICK_SOUND.playFor(p);
|
||||
Slimefun.getLocalization().sendMessage(p, "messages.auto-crafting.recipe-removed");
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,6 @@ import javax.annotation.ParametersAreNonnullByDefault;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.block.Skull;
|
||||
@ -21,6 +20,7 @@ import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup;
|
||||
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem;
|
||||
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
|
||||
import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
|
||||
import io.github.thebusybiscuit.slimefun4.core.services.sounds.SoundEffect;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.tasks.AsyncRecipeChoiceTask;
|
||||
import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils;
|
||||
@ -98,7 +98,7 @@ public class SlimefunAutoCrafter extends AbstractAutoCrafter {
|
||||
menu.addItem(49, new CustomItemStack(Material.CRAFTING_TABLE, ChatColor.GREEN + Slimefun.getLocalization().getMessage(p, "messages.auto-crafting.select")));
|
||||
menu.addMenuClickHandler(49, (pl, stack, slot, action) -> {
|
||||
setSelectedRecipe(b, recipe);
|
||||
p.playSound(p.getLocation(), Sound.UI_BUTTON_CLICK, 1, 1);
|
||||
SoundEffect.AUTO_CRAFTER_UPDATE_RECIPE.playAt(b);
|
||||
Slimefun.getLocalization().sendMessage(p, "messages.auto-crafting.recipe-set");
|
||||
showRecipe(p, b, recipe);
|
||||
return false;
|
||||
@ -108,7 +108,7 @@ public class SlimefunAutoCrafter extends AbstractAutoCrafter {
|
||||
recipe.show(menu, task);
|
||||
menu.open(p);
|
||||
|
||||
p.playSound(p.getLocation(), Sound.UI_BUTTON_CLICK, 1, 1);
|
||||
SoundEffect.AUTO_CRAFTER_UPDATE_RECIPE.playAt(b);;
|
||||
|
||||
if (!task.isEmpty()) {
|
||||
task.start(menu.toInventory());
|
||||
|
@ -12,7 +12,7 @@ import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.SoundCategory;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.block.Skull;
|
||||
@ -31,6 +31,7 @@ import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem;
|
||||
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
|
||||
import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
|
||||
import io.github.thebusybiscuit.slimefun4.core.services.MinecraftRecipeService;
|
||||
import io.github.thebusybiscuit.slimefun4.core.services.sounds.SoundEffect;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.tasks.AsyncRecipeChoiceTask;
|
||||
import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils;
|
||||
@ -123,7 +124,7 @@ public class VanillaAutoCrafter extends AbstractAutoCrafter {
|
||||
|
||||
menu.open(p);
|
||||
task.start(menu.toInventory());
|
||||
p.playSound(p.getLocation(), Sound.UI_BUTTON_CLICK, 1, 1);
|
||||
SoundEffect.VANILLA_AUTO_CRAFTER_UPDATE_RECIPE_SOUND.playAt(p.getLocation(), SoundCategory.PLAYERS);
|
||||
}
|
||||
}
|
||||
|
||||
@ -134,7 +135,7 @@ public class VanillaAutoCrafter extends AbstractAutoCrafter {
|
||||
menu.replaceExistingItem(46, ChestMenuUtils.getPreviousButton(p, index + 1, recipes.size()));
|
||||
menu.addMenuClickHandler(46, (pl, slot, item, action) -> {
|
||||
if (index > 0) {
|
||||
pl.playSound(pl.getLocation(), Sound.UI_BUTTON_CLICK, 1, 1);
|
||||
SoundEffect.AUTO_CRAFTER_GUI_CLICK_SOUND.playFor(pl);
|
||||
offerRecipe(p, b, recipes, index - 1, menu, task);
|
||||
}
|
||||
|
||||
@ -144,7 +145,7 @@ public class VanillaAutoCrafter extends AbstractAutoCrafter {
|
||||
menu.replaceExistingItem(52, ChestMenuUtils.getNextButton(p, index + 1, recipes.size()));
|
||||
menu.addMenuClickHandler(52, (pl, slot, item, action) -> {
|
||||
if (index < (recipes.size() - 1)) {
|
||||
pl.playSound(pl.getLocation(), Sound.UI_BUTTON_CLICK, 1, 1);
|
||||
SoundEffect.AUTO_CRAFTER_GUI_CLICK_SOUND.playFor(pl);
|
||||
offerRecipe(p, b, recipes, index + 1, menu, task);
|
||||
}
|
||||
|
||||
@ -158,7 +159,7 @@ public class VanillaAutoCrafter extends AbstractAutoCrafter {
|
||||
setSelectedRecipe(b, recipe);
|
||||
pl.closeInventory();
|
||||
|
||||
p.playSound(p.getLocation(), Sound.UI_BUTTON_CLICK, 1, 1);
|
||||
SoundEffect.AUTO_CRAFTER_GUI_CLICK_SOUND.playFor(pl);
|
||||
Slimefun.getLocalization().sendMessage(p, "messages.auto-crafting.recipe-set");
|
||||
showRecipe(p, b, recipe);
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
package io.github.thebusybiscuit.slimefun4.implementation.items.backpacks;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.block.EnderChest;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
@ -13,6 +13,7 @@ import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
|
||||
import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
|
||||
import io.github.thebusybiscuit.slimefun4.core.attributes.NotPlaceable;
|
||||
import io.github.thebusybiscuit.slimefun4.core.handlers.ItemUseHandler;
|
||||
import io.github.thebusybiscuit.slimefun4.core.services.sounds.SoundEffect;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
|
||||
|
||||
/**
|
||||
@ -30,11 +31,11 @@ public class EnderBackpack extends SimpleSlimefunItem<ItemUseHandler> implements
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemUseHandler getItemHandler() {
|
||||
public @Nonnull ItemUseHandler getItemHandler() {
|
||||
return e -> {
|
||||
Player p = e.getPlayer();
|
||||
p.openInventory(p.getEnderChest());
|
||||
p.playSound(p.getEyeLocation(), Sound.ENTITY_ENDERMAN_TELEPORT, 1F, 1F);
|
||||
SoundEffect.ENDER_BACKPACK_OPEN_SOUND.playFor(p);
|
||||
e.cancel();
|
||||
};
|
||||
}
|
||||
|
@ -6,16 +6,19 @@ import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup;
|
||||
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem;
|
||||
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
|
||||
import io.github.thebusybiscuit.slimefun4.api.player.PlayerBackpack;
|
||||
import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
|
||||
import io.github.thebusybiscuit.slimefun4.core.attributes.DistinctiveItem;
|
||||
import io.github.thebusybiscuit.slimefun4.core.handlers.ItemUseHandler;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.listeners.BackpackListener;
|
||||
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
|
||||
import io.github.thebusybiscuit.slimefun4.utils.tags.SlimefunTag;
|
||||
|
||||
/**
|
||||
@ -28,7 +31,7 @@ import io.github.thebusybiscuit.slimefun4.utils.tags.SlimefunTag;
|
||||
* @see PlayerBackpack
|
||||
*
|
||||
*/
|
||||
public class SlimefunBackpack extends SimpleSlimefunItem<ItemUseHandler> {
|
||||
public class SlimefunBackpack extends SimpleSlimefunItem<ItemUseHandler> implements DistinctiveItem {
|
||||
|
||||
private final int size;
|
||||
|
||||
@ -82,4 +85,14 @@ public class SlimefunBackpack extends SimpleSlimefunItem<ItemUseHandler> {
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canStack(@Nonnull ItemMeta itemMetaOne, @Nonnull ItemMeta itemMetaTwo) {
|
||||
boolean hasLoreItem = itemMetaTwo.hasLore();
|
||||
boolean hasLoreSfItem = itemMetaOne.hasLore();
|
||||
|
||||
if (hasLoreItem && hasLoreSfItem && SlimefunUtils.equalsLore(itemMetaTwo.getLore(), itemMetaOne.getLore())) {
|
||||
return true;
|
||||
}
|
||||
return !hasLoreItem && !hasLoreSfItem;
|
||||
}
|
||||
}
|
||||
|
@ -10,7 +10,6 @@ import javax.annotation.ParametersAreNonnullByDefault;
|
||||
import org.bukkit.Effect;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.Tag;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
@ -25,6 +24,7 @@ import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
|
||||
import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
|
||||
import io.github.thebusybiscuit.slimefun4.core.attributes.RecipeDisplayItem;
|
||||
import io.github.thebusybiscuit.slimefun4.core.handlers.BlockUseHandler;
|
||||
import io.github.thebusybiscuit.slimefun4.core.services.sounds.SoundEffect;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
|
||||
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
|
||||
@ -94,7 +94,7 @@ public class Composter extends SimpleSlimefunItem<BlockUseHandler> implements Re
|
||||
});
|
||||
|
||||
tasks.thenRun(20, () -> {
|
||||
p.getWorld().playSound(p.getLocation(), Sound.ENTITY_ARROW_HIT_PLAYER, 1F, 1F);
|
||||
SoundEffect.COMPOSTER_COMPOST_SOUND.playFor(p);
|
||||
pushItem(b, output.clone());
|
||||
});
|
||||
|
||||
|
@ -9,7 +9,6 @@ import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Particle;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.Tag;
|
||||
import org.bukkit.World.Environment;
|
||||
import org.bukkit.block.Block;
|
||||
@ -27,6 +26,7 @@ import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
|
||||
import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
|
||||
import io.github.thebusybiscuit.slimefun4.core.attributes.RecipeDisplayItem;
|
||||
import io.github.thebusybiscuit.slimefun4.core.handlers.BlockUseHandler;
|
||||
import io.github.thebusybiscuit.slimefun4.core.services.sounds.SoundEffect;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
|
||||
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
|
||||
@ -166,7 +166,7 @@ public class Crucible extends SimpleSlimefunItem<BlockUseHandler> implements Rec
|
||||
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);
|
||||
SoundEffect.CRUCIBLE_GENERATE_LIQUID_SOUND.playAt(block);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -175,7 +175,7 @@ public class Crucible extends SimpleSlimefunItem<BlockUseHandler> implements Rec
|
||||
} else if (block.getType() == (isWater ? Material.LAVA : Material.WATER)) {
|
||||
int level = ((Levelled) block.getBlockData()).getLevel();
|
||||
block.setType(level == 0 || level == 8 ? Material.OBSIDIAN : Material.STONE);
|
||||
block.getWorld().playSound(block.getLocation(), Sound.BLOCK_LAVA_EXTINGUISH, 1F, 1F);
|
||||
SoundEffect.CRUCIBLE_GENERATE_LIQUID_SOUND.playAt(block);
|
||||
} else {
|
||||
Slimefun.runSync(() -> placeLiquid(block, isWater), 50L);
|
||||
}
|
||||
@ -189,10 +189,10 @@ public class Crucible extends SimpleSlimefunItem<BlockUseHandler> implements Rec
|
||||
}
|
||||
|
||||
if (level == 0) {
|
||||
block.getWorld().playSound(block.getLocation(), water ? Sound.ENTITY_PLAYER_SPLASH : Sound.BLOCK_LAVA_POP, 1F, 1F);
|
||||
Slimefun.runSync(() -> runPostTask(block, water ? SoundEffect.CRUCIBLE_ADD_WATER_SOUND : SoundEffect.CRUCIBLE_ADD_LAVA_SOUND, 1));
|
||||
} else {
|
||||
int finalLevel = 7 - level;
|
||||
Slimefun.runSync(() -> runPostTask(block, water ? Sound.ENTITY_PLAYER_SPLASH : Sound.BLOCK_LAVA_POP, finalLevel), 50L);
|
||||
Slimefun.runSync(() -> runPostTask(block, water ? SoundEffect.CRUCIBLE_ADD_WATER_SOUND : SoundEffect.CRUCIBLE_ADD_LAVA_SOUND, finalLevel), 50L);
|
||||
}
|
||||
}
|
||||
|
||||
@ -204,7 +204,7 @@ public class Crucible extends SimpleSlimefunItem<BlockUseHandler> implements Rec
|
||||
if (water && block.getBlockData() instanceof Waterlogged waterlogged) {
|
||||
waterlogged.setWaterlogged(true);
|
||||
block.setBlockData(waterlogged, false);
|
||||
block.getWorld().playSound(block.getLocation(), Sound.ENTITY_PLAYER_SPLASH, 1F, 1F);
|
||||
SoundEffect.CRUCIBLE_PLACE_WATER_SOUND.playAt(block);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -212,18 +212,17 @@ public class Crucible extends SimpleSlimefunItem<BlockUseHandler> implements Rec
|
||||
BlockStorage.clearBlockInfo(block);
|
||||
}
|
||||
}
|
||||
|
||||
runPostTask(block, water ? Sound.ENTITY_PLAYER_SPLASH : Sound.BLOCK_LAVA_POP, 1);
|
||||
runPostTask(block, water ? SoundEffect.CRUCIBLE_PLACE_WATER_SOUND : SoundEffect.CRUCIBLE_PLACE_LAVA_SOUND, 1);
|
||||
}
|
||||
|
||||
@ParametersAreNonnullByDefault
|
||||
private void runPostTask(Block block, Sound sound, int times) {
|
||||
private void runPostTask(Block block, SoundEffect sound, int times) {
|
||||
if (!(block.getBlockData() instanceof Levelled le)) {
|
||||
block.getWorld().playSound(block.getLocation(), Sound.BLOCK_METAL_BREAK, 1F, 1F);
|
||||
SoundEffect.CRUCIBLE_BLOCK_BREAK_SOUND.playAt(block);
|
||||
return;
|
||||
}
|
||||
|
||||
block.getWorld().playSound(block.getLocation(), sound, 1F, 1F);
|
||||
sound.playAt(block);
|
||||
int level = 8 - times;
|
||||
le.setLevel(level);
|
||||
block.setBlockData(le, false);
|
||||
@ -231,7 +230,7 @@ public class Crucible extends SimpleSlimefunItem<BlockUseHandler> implements Rec
|
||||
if (times < 8) {
|
||||
Slimefun.runSync(() -> runPostTask(block, sound, times + 1), 50L);
|
||||
} else {
|
||||
block.getWorld().playSound(block.getLocation(), Sound.ENTITY_ARROW_HIT_PLAYER, 1F, 1F);
|
||||
SoundEffect.CRUCIBLE_INTERACT_SOUND.playAt(block);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,6 @@ import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.ArmorStand;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.block.BlockPlaceEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
@ -26,6 +25,7 @@ import io.github.thebusybiscuit.slimefun4.core.handlers.BlockUseHandler;
|
||||
import io.github.thebusybiscuit.slimefun4.core.services.holograms.HologramsService;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.handlers.SimpleBlockBreakHandler;
|
||||
import io.github.thebusybiscuit.slimefun4.utils.ArmorStandUtils;
|
||||
import io.github.thebusybiscuit.slimefun4.utils.ChatUtils;
|
||||
import io.github.thebusybiscuit.slimefun4.utils.NumberUtils;
|
||||
|
||||
@ -153,21 +153,7 @@ public class HologramProjector extends SlimefunItem implements HologramOwner {
|
||||
return null;
|
||||
}
|
||||
|
||||
ArmorStand hologram = spawnArmorStand(l);
|
||||
hologram.setCustomName(nametag);
|
||||
return hologram;
|
||||
}
|
||||
|
||||
private static @Nonnull ArmorStand spawnArmorStand(@Nonnull Location l) {
|
||||
ArmorStand armorStand = (ArmorStand) l.getWorld().spawnEntity(l, EntityType.ARMOR_STAND);
|
||||
armorStand.setVisible(false);
|
||||
armorStand.setSilent(true);
|
||||
armorStand.setMarker(true);
|
||||
armorStand.setGravity(false);
|
||||
armorStand.setBasePlate(false);
|
||||
armorStand.setCustomNameVisible(true);
|
||||
armorStand.setRemoveWhenFarAway(false);
|
||||
return armorStand;
|
||||
return ArmorStandUtils.spawnArmorStand(l, nametag);
|
||||
}
|
||||
|
||||
private static void killArmorStand(@Nonnull Block b) {
|
||||
|
@ -6,7 +6,6 @@ import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.BlockState;
|
||||
@ -22,6 +21,7 @@ import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup;
|
||||
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem;
|
||||
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
|
||||
import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
|
||||
import io.github.thebusybiscuit.slimefun4.core.services.sounds.SoundEffect;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.handlers.VanillaInventoryDropHandler;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.items.multiblocks.Smeltery;
|
||||
@ -94,13 +94,13 @@ public class IgnitionChamber extends SlimefunItem {
|
||||
if (((Damageable) meta).getDamage() >= item.getType().getMaxDurability()) {
|
||||
// The Flint and Steel broke
|
||||
item.setAmount(0);
|
||||
smelteryBlock.getWorld().playSound(smelteryBlock.getLocation(), Sound.ENTITY_ITEM_BREAK, 1, 1);
|
||||
SoundEffect.IGNITION_CHAMBER_USE_FLINT_AND_STEEL_SOUND.playAt(smelteryBlock);
|
||||
} else {
|
||||
item.setItemMeta(meta);
|
||||
}
|
||||
}
|
||||
|
||||
smelteryBlock.getWorld().playSound(smelteryBlock.getLocation(), Sound.ITEM_FLINTANDSTEEL_USE, 1, 1);
|
||||
SoundEffect.IGNITION_CHAMBER_USE_FLINT_AND_STEEL_SOUND.playAt(smelteryBlock);
|
||||
return true;
|
||||
} else {
|
||||
// Notify the Player there is a chamber but without any Flint and Steel
|
||||
|
@ -9,7 +9,7 @@ import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem;
|
||||
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
|
||||
import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
|
||||
import io.github.thebusybiscuit.slimefun4.core.attributes.Rechargeable;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.tasks.JetBootsTask;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.tasks.player.JetBootsTask;
|
||||
|
||||
/**
|
||||
* {@link JetBoots} allow you to hover for a bit.
|
||||
|
@ -9,7 +9,7 @@ import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem;
|
||||
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
|
||||
import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
|
||||
import io.github.thebusybiscuit.slimefun4.core.attributes.Rechargeable;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.tasks.JetpackTask;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.tasks.player.JetpackTask;
|
||||
|
||||
/**
|
||||
* {@link JetBoots} allow you to fly up into the air.
|
||||
|
@ -15,7 +15,7 @@ import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
|
||||
import io.github.thebusybiscuit.slimefun4.api.items.settings.DoubleRangeSetting;
|
||||
import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
|
||||
import io.github.thebusybiscuit.slimefun4.core.attributes.Rechargeable;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.tasks.ArmorTask;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.tasks.armor.SolarHelmetTask;
|
||||
|
||||
/**
|
||||
* The {@link SolarHelmet} can be worn by {@link Player}.
|
||||
@ -25,7 +25,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.tasks.ArmorTask;
|
||||
*
|
||||
* @author TheBusyBiscuit
|
||||
*
|
||||
* @see ArmorTask
|
||||
* @see SolarHelmetTask
|
||||
* @see Rechargeable
|
||||
*
|
||||
*/
|
||||
|
@ -1,5 +1,6 @@
|
||||
package io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
import org.bukkit.Material;
|
||||
@ -45,27 +46,30 @@ public class ElectricDustWasher extends AContainer {
|
||||
@Override
|
||||
protected MachineRecipe findNextRecipe(BlockMenu menu) {
|
||||
for (int slot : getInputSlots()) {
|
||||
if (SlimefunUtils.isItemSimilar(menu.getItemInSlot(slot), SlimefunItems.SIFTED_ORE, true, false)) {
|
||||
ItemStack input = menu.getItemInSlot(slot);
|
||||
MachineRecipe recipe = null;
|
||||
if (SlimefunUtils.isItemSimilar(input, SlimefunItems.SIFTED_ORE, true, false)) {
|
||||
if (!legacyMode && !hasFreeSlot(menu)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
ItemStack dust = oreWasher.getRandomDust();
|
||||
MachineRecipe recipe = new MachineRecipe(4 / getSpeed(), new ItemStack[] { SlimefunItems.SIFTED_ORE }, new ItemStack[] { dust });
|
||||
recipe = new MachineRecipe(4 / getSpeed(), new ItemStack[] { SlimefunItems.SIFTED_ORE }, new ItemStack[] { oreWasher.getRandomDust() });
|
||||
|
||||
if (!legacyMode || menu.fits(recipe.getOutput()[0], getOutputSlots())) {
|
||||
menu.consumeItem(slot);
|
||||
return recipe;
|
||||
}
|
||||
} else if (SlimefunUtils.isItemSimilar(menu.getItemInSlot(slot), SlimefunItems.PULVERIZED_ORE, true)) {
|
||||
MachineRecipe recipe = new MachineRecipe(4 / getSpeed(), new ItemStack[] { SlimefunItems.PULVERIZED_ORE }, new ItemStack[] { SlimefunItems.PURE_ORE_CLUSTER });
|
||||
} else if (SlimefunUtils.isItemSimilar(input, SlimefunItems.PULVERIZED_ORE, true)) {
|
||||
recipe = new MachineRecipe(4 / getSpeed(), new ItemStack[] { SlimefunItems.PULVERIZED_ORE }, new ItemStack[] { SlimefunItems.PURE_ORE_CLUSTER });
|
||||
} else if (SlimefunUtils.isItemSimilar(input, new ItemStack(Material.SAND), true)) {
|
||||
recipe = new MachineRecipe(4 / getSpeed(), new ItemStack[] { new ItemStack(Material.SAND) }, new ItemStack[] { SlimefunItems.SALT });
|
||||
}
|
||||
|
||||
if (menu.fits(recipe.getOutput()[0], getOutputSlots())) {
|
||||
if (recipe != null && menu.fits(recipe.getOutput()[0], getOutputSlots())) {
|
||||
menu.consumeItem(slot);
|
||||
return recipe;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
@ -83,7 +87,7 @@ public class ElectricDustWasher extends AContainer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMachineIdentifier() {
|
||||
public @Nonnull String getMachineIdentifier() {
|
||||
return "ELECTRIC_DUST_WASHER";
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,6 @@ import io.github.thebusybiscuit.slimefun4.core.attributes.RecipeDisplayItem;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.items.tools.GoldPan;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.items.tools.NetherGoldPan;
|
||||
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
|
||||
|
||||
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AContainer;
|
||||
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.MachineRecipe;
|
||||
@ -28,10 +27,11 @@ import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu;
|
||||
* It also serves as a {@link NetherGoldPan}.
|
||||
*
|
||||
* @author TheBusyBiscuit
|
||||
* @author svr333
|
||||
* @author JustAHuman
|
||||
*
|
||||
* @see GoldPan
|
||||
* @see NetherGoldPan
|
||||
*
|
||||
*/
|
||||
public class ElectricGoldPan extends AContainer implements RecipeDisplayItem {
|
||||
|
||||
@ -40,9 +40,6 @@ public class ElectricGoldPan extends AContainer implements RecipeDisplayItem {
|
||||
private final GoldPan goldPan = SlimefunItems.GOLD_PAN.getItem(GoldPan.class);
|
||||
private final GoldPan netherGoldPan = SlimefunItems.NETHER_GOLD_PAN.getItem(GoldPan.class);
|
||||
|
||||
private final ItemStack gravel = new ItemStack(Material.GRAVEL);
|
||||
private final ItemStack soulSand = new ItemStack(Material.SOUL_SAND);
|
||||
|
||||
@ParametersAreNonnullByDefault
|
||||
public ElectricGoldPan(ItemGroup itemGroup, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
||||
super(itemGroup, item, recipeType, recipe);
|
||||
@ -50,21 +47,30 @@ public class ElectricGoldPan extends AContainer implements RecipeDisplayItem {
|
||||
}
|
||||
|
||||
/**
|
||||
* This returns whether the {@link ElectricGoldPan} will stop proccessing inputs
|
||||
* @deprecated since RC-36
|
||||
* Use {@link ElectricGoldPan#isOutputLimitOverridden()} instead.
|
||||
*/
|
||||
@Deprecated(since = "RC-36")
|
||||
public boolean isOutputLimitOverriden() {
|
||||
return isOutputLimitOverridden();
|
||||
}
|
||||
|
||||
/**
|
||||
* This returns whether the {@link ElectricGoldPan} will stop processing inputs
|
||||
* if both output slots contain items or if that default behavior should be
|
||||
* overriden and allow the {@link ElectricGoldPan} to continue processing inputs
|
||||
* overridden and allow the {@link ElectricGoldPan} to continue processing inputs
|
||||
* even if both output slots are occupied. Note this option will allow players
|
||||
* to force specific outputs from the {@link ElectricGoldPan} but can be
|
||||
* necessary when a server has disabled cargo networks.
|
||||
*
|
||||
* @return If output limits are overriden
|
||||
* @return If output limits are overridden
|
||||
*/
|
||||
public boolean isOutputLimitOverriden() {
|
||||
public boolean isOutputLimitOverridden() {
|
||||
return overrideOutputLimit.getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ItemStack> getDisplayRecipes() {
|
||||
public @Nonnull List<ItemStack> getDisplayRecipes() {
|
||||
List<ItemStack> recipes = new ArrayList<>();
|
||||
|
||||
recipes.addAll(goldPan.getDisplayRecipes());
|
||||
@ -80,30 +86,26 @@ public class ElectricGoldPan extends AContainer implements RecipeDisplayItem {
|
||||
|
||||
@Override
|
||||
protected MachineRecipe findNextRecipe(BlockMenu menu) {
|
||||
if (!isOutputLimitOverriden() && !hasFreeSlot(menu)) {
|
||||
if (!isOutputLimitOverridden() && !hasFreeSlot(menu)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
for (int slot : getInputSlots()) {
|
||||
ItemStack item = menu.getItemInSlot(slot);
|
||||
MachineRecipe recipe = null;
|
||||
ItemStack output = null;
|
||||
|
||||
if (SlimefunUtils.isItemSimilar(item, gravel, true, false)) {
|
||||
ItemStack output = goldPan.getRandomOutput();
|
||||
MachineRecipe recipe = new MachineRecipe(3 / getSpeed(), new ItemStack[] { gravel }, new ItemStack[] { output });
|
||||
|
||||
if (output.getType() != Material.AIR && menu.fits(output, getOutputSlots())) {
|
||||
menu.consumeItem(slot);
|
||||
return recipe;
|
||||
}
|
||||
} else if (SlimefunUtils.isItemSimilar(item, soulSand, true, false)) {
|
||||
ItemStack output = netherGoldPan.getRandomOutput();
|
||||
MachineRecipe recipe = new MachineRecipe(4 / getSpeed(), new ItemStack[] { soulSand }, new ItemStack[] { output });
|
||||
|
||||
if (output.getType() != Material.AIR && menu.fits(output, getOutputSlots())) {
|
||||
menu.consumeItem(slot);
|
||||
return recipe;
|
||||
if (goldPan.isValidInput(item)) {
|
||||
output = goldPan.getRandomOutput();
|
||||
recipe = new MachineRecipe(3 / getSpeed(), new ItemStack[] { item }, new ItemStack[] { output });
|
||||
} else if (netherGoldPan.isValidInput(item)) {
|
||||
output = netherGoldPan.getRandomOutput();
|
||||
recipe = new MachineRecipe(4 / getSpeed(), new ItemStack[] { item }, new ItemStack[] { output });
|
||||
}
|
||||
|
||||
if (output != null && output.getType() != Material.AIR && menu.fits(output, getOutputSlots())) {
|
||||
menu.consumeItem(slot);
|
||||
return recipe;
|
||||
}
|
||||
}
|
||||
|
||||
@ -121,7 +123,7 @@ public class ElectricGoldPan extends AContainer implements RecipeDisplayItem {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMachineIdentifier() {
|
||||
public @Nonnull String getMachineIdentifier() {
|
||||
return "ELECTRIC_GOLD_PAN";
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,7 @@ import javax.annotation.Nonnull;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Item;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
@ -28,6 +29,7 @@ import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu;
|
||||
*
|
||||
* @author TheBusyBiscuit
|
||||
* @author Rothes
|
||||
* @author J3fftw1
|
||||
*
|
||||
* @see AutoEnchanter
|
||||
* @see AutoDisenchanter
|
||||
@ -37,6 +39,8 @@ abstract class AbstractEnchantmentMachine extends AContainer {
|
||||
|
||||
private final ItemSetting<Boolean> useLevelLimit = new ItemSetting<>(this, "use-enchant-level-limit", false);
|
||||
private final IntRangeSetting levelLimit = new IntRangeSetting(this, "enchant-level-limit", 0, 10, Short.MAX_VALUE);
|
||||
private final ItemSetting<Integer> maxEnchants = new IntRangeSetting(this, "max-enchants", 0, 10, Short.MAX_VALUE);
|
||||
private final ItemSetting<Boolean> useMaxEnchants= new ItemSetting<>(this, "use-max-enchants", false);
|
||||
private final ItemSetting<Boolean> useIgnoredLores = new ItemSetting<>(this, "use-ignored-lores", false);
|
||||
private final ItemSetting<List<String>> ignoredLores = new ItemSetting<>(this, "ignored-lores", Collections.singletonList("&7- &cCan't be used in " + this.getItemName()));
|
||||
|
||||
@ -48,6 +52,8 @@ abstract class AbstractEnchantmentMachine extends AContainer {
|
||||
addItemSetting(levelLimit);
|
||||
addItemSetting(useIgnoredLores);
|
||||
addItemSetting(ignoredLores);
|
||||
addItemSetting(maxEnchants);
|
||||
addItemSetting(useMaxEnchants);
|
||||
}
|
||||
|
||||
protected boolean isEnchantmentLevelAllowed(int enchantmentLevel) {
|
||||
@ -84,4 +90,11 @@ abstract class AbstractEnchantmentMachine extends AContainer {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected boolean isEnchantmentAmountAllowed(int numberOfEnchants) {
|
||||
if (!useMaxEnchants.getValue()) {
|
||||
return true;
|
||||
}
|
||||
return numberOfEnchants <= maxEnchants.getValue();
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package io.github.thebusybiscuit.slimefun4.implementation.items.electric.machine
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
@ -20,6 +21,8 @@ import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup;
|
||||
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem;
|
||||
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
|
||||
import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
|
||||
|
||||
|
||||
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.MachineRecipe;
|
||||
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu;
|
||||
@ -94,6 +97,10 @@ public class AutoDisenchanter extends AbstractEnchantmentMachine {
|
||||
}
|
||||
}
|
||||
|
||||
if (!isEnchantmentAmountAllowed(enchantments.size())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Check if we found any valid enchantments
|
||||
if (!enchantments.isEmpty()) {
|
||||
ItemStack disenchantedItem = item.clone();
|
||||
@ -124,16 +131,25 @@ public class AutoDisenchanter extends AbstractEnchantmentMachine {
|
||||
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);
|
||||
Enchantment enchantmentToTransfer = entry.getKey();
|
||||
boolean wasEnchantmentRemoved = itemMeta.removeEnchant(enchantmentToTransfer);
|
||||
boolean stillHasEnchantment = itemMeta.getEnchants().containsKey(enchantmentToTransfer);
|
||||
|
||||
// Prevent future enchantment duplication (#3837)
|
||||
if (wasEnchantmentRemoved && !stillHasEnchantment) {
|
||||
meta.addStoredEnchant(enchantmentToTransfer, entry.getValue(), true);
|
||||
} else {
|
||||
// Get Enchantment Name
|
||||
Slimefun.logger().log(Level.SEVERE, "AutoDisenchanter has failed to remove enchantment \"{0}\"", enchantmentToTransfer.getKey().getKey());
|
||||
}
|
||||
}
|
||||
|
||||
item.setItemMeta(itemMeta);
|
||||
book.setItemMeta(meta);
|
||||
}
|
||||
|
||||
|
@ -116,6 +116,22 @@ public class AutoEnchanter extends AbstractEnchantmentMachine {
|
||||
enchantments.entrySet().removeIf(e -> target.getEnchantmentLevel(e.getKey()) >= e.getValue());
|
||||
}
|
||||
|
||||
/*
|
||||
* When maxEnchants is set to -1 it will be ignored. When it's set to 0 it will not allow any enchants to go
|
||||
* on an item. When maxEnchants is set to any other value it will allow that many enchants to go on the item.
|
||||
*/
|
||||
int preExistingEnchants = 0;
|
||||
for (Map.Entry<Enchantment, Integer> entry : target.getEnchantments().entrySet()) {
|
||||
if (meta.hasEnchant(entry.getKey())) {
|
||||
preExistingEnchants++;
|
||||
}
|
||||
}
|
||||
int totalEnchants = enchantments.size() + preExistingEnchants;
|
||||
|
||||
if (!isEnchantmentAmountAllowed(totalEnchants)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Check if we found any valid enchantments
|
||||
if (!enchantments.isEmpty()) {
|
||||
ItemStack enchantedItem = target.clone();
|
||||
|
@ -5,6 +5,7 @@ import java.util.Iterator;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Entity;
|
||||
@ -123,46 +124,59 @@ public class ExpCollector extends SlimefunItem implements InventoryBlock, Energy
|
||||
});
|
||||
}
|
||||
|
||||
protected void tick(Block b) {
|
||||
Iterator<Entity> iterator = b.getWorld().getNearbyEntities(b.getLocation(), 4.0, 4.0, 4.0, n -> n instanceof ExperienceOrb && n.isValid()).iterator();
|
||||
protected void tick(Block block) {
|
||||
Location location = block.getLocation();
|
||||
Iterator<Entity> iterator = block.getWorld().getNearbyEntities(location, 4.0, 4.0, 4.0, n -> n instanceof ExperienceOrb && n.isValid()).iterator();
|
||||
int experiencePoints = 0;
|
||||
|
||||
while (iterator.hasNext() && experiencePoints == 0) {
|
||||
Entity entity = iterator.next();
|
||||
ExperienceOrb orb = (ExperienceOrb) iterator.next();
|
||||
|
||||
if (getCharge(b.getLocation()) < ENERGY_CONSUMPTION) {
|
||||
if (getCharge(location) < ENERGY_CONSUMPTION) {
|
||||
return;
|
||||
}
|
||||
|
||||
experiencePoints = getStoredExperience(b) + ((ExperienceOrb) entity).getExperience();
|
||||
experiencePoints = getStoredExperience(location) + orb.getExperience();
|
||||
|
||||
removeCharge(b.getLocation(), ENERGY_CONSUMPTION);
|
||||
entity.remove();
|
||||
removeCharge(location, ENERGY_CONSUMPTION);
|
||||
orb.remove();
|
||||
produceFlasks(location, experiencePoints);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Produces Flasks of Knowledge for the given block until it either uses all stored
|
||||
* experience or runs out of room.
|
||||
*
|
||||
* @param location
|
||||
* The {@link Location} of the {@link ExpCollector} to produce flasks in.
|
||||
* @param experiencePoints
|
||||
* The number of experience points to use during production.
|
||||
*/
|
||||
private void produceFlasks(@Nonnull Location location, int experiencePoints) {
|
||||
int withdrawn = 0;
|
||||
BlockMenu menu = BlockStorage.getInventory(b);
|
||||
|
||||
for (int level = 0; level < getStoredExperience(b); level = level + 10) {
|
||||
BlockMenu menu = BlockStorage.getInventory(location);
|
||||
for (int level = 0; level < getStoredExperience(location); level = level + 10) {
|
||||
if (menu.fits(SlimefunItems.FILLED_FLASK_OF_KNOWLEDGE, getOutputSlots())) {
|
||||
withdrawn = withdrawn + 10;
|
||||
menu.pushItem(SlimefunItems.FILLED_FLASK_OF_KNOWLEDGE.clone(), getOutputSlots());
|
||||
} else {
|
||||
// There is no room for more bottles, so lets stop checking if more will fit.
|
||||
break;
|
||||
}
|
||||
}
|
||||
BlockStorage.addBlockInfo(location, DATA_KEY, String.valueOf(experiencePoints - withdrawn));
|
||||
}
|
||||
|
||||
BlockStorage.addBlockInfo(b, DATA_KEY, String.valueOf(experiencePoints - withdrawn));
|
||||
}
|
||||
}
|
||||
|
||||
private int getStoredExperience(Block b) {
|
||||
Config cfg = BlockStorage.getLocationInfo(b.getLocation());
|
||||
private int getStoredExperience(Location location) {
|
||||
Config cfg = BlockStorage.getLocationInfo(location);
|
||||
String value = cfg.getString(DATA_KEY);
|
||||
|
||||
if (value != null) {
|
||||
return Integer.parseInt(value);
|
||||
} else {
|
||||
BlockStorage.addBlockInfo(b, DATA_KEY, "0");
|
||||
BlockStorage.addBlockInfo(location, DATA_KEY, "0");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.SoundCategory;
|
||||
import org.bukkit.entity.IronGolem;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
@ -12,6 +12,7 @@ import io.github.bakedlibs.dough.items.CustomItemStack;
|
||||
import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup;
|
||||
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
|
||||
import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
|
||||
import io.github.thebusybiscuit.slimefun4.core.services.sounds.SoundEffect;
|
||||
import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils;
|
||||
|
||||
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset;
|
||||
@ -71,8 +72,7 @@ public class IronGolemAssembler extends AbstractEntityAssembler<IronGolem> {
|
||||
|
||||
@Override
|
||||
public IronGolem spawnEntity(Location l) {
|
||||
l.getWorld().playSound(l, Sound.ENTITY_IRON_GOLEM_REPAIR, 0.5F, 1);
|
||||
SoundEffect.IRON_GOLEM_ASSEMBLER_ASSEMBLE_SOUND.playAt(l, SoundCategory.BLOCKS);
|
||||
return l.getWorld().spawn(l, IronGolem.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
package io.github.thebusybiscuit.slimefun4.implementation.items.food;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
@ -11,6 +11,7 @@ import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup;
|
||||
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
|
||||
import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
|
||||
import io.github.thebusybiscuit.slimefun4.core.handlers.ItemConsumptionHandler;
|
||||
import io.github.thebusybiscuit.slimefun4.core.services.sounds.SoundEffect;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
|
||||
|
||||
@ -32,10 +33,10 @@ public class DietCookie extends SimpleSlimefunItem<ItemConsumptionHandler> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemConsumptionHandler getItemHandler() {
|
||||
public @Nonnull ItemConsumptionHandler getItemHandler() {
|
||||
return (e, p, item) -> {
|
||||
Slimefun.getLocalization().sendMessage(p, "messages.diet-cookie");
|
||||
p.playSound(p.getLocation(), Sound.ENTITY_GENERIC_EAT, 1, 1);
|
||||
SoundEffect.DIET_COOKIE_CONSUME_SOUND.playFor(p);
|
||||
|
||||
if (p.hasPotionEffect(PotionEffectType.LEVITATION)) {
|
||||
p.removePotionEffect(PotionEffectType.LEVITATION);
|
||||
@ -44,5 +45,4 @@ public class DietCookie extends SimpleSlimefunItem<ItemConsumptionHandler> {
|
||||
p.addPotionEffect(PotionEffectType.LEVITATION.createEffect(60, 1));
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,10 +1,10 @@
|
||||
package io.github.thebusybiscuit.slimefun4.implementation.items.food;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
@ -15,6 +15,7 @@ import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup;
|
||||
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
|
||||
import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
|
||||
import io.github.thebusybiscuit.slimefun4.core.handlers.ItemUseHandler;
|
||||
import io.github.thebusybiscuit.slimefun4.core.services.sounds.SoundEffect;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
|
||||
|
||||
/**
|
||||
@ -32,7 +33,7 @@ public class MagicSugar extends SimpleSlimefunItem<ItemUseHandler> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemUseHandler getItemHandler() {
|
||||
public @Nonnull ItemUseHandler getItemHandler() {
|
||||
return e -> {
|
||||
// Check if it is being placed into an ancient altar.
|
||||
if (e.getClickedBlock().isPresent()) {
|
||||
@ -49,7 +50,7 @@ public class MagicSugar extends SimpleSlimefunItem<ItemUseHandler> {
|
||||
ItemUtils.consumeItem(e.getItem(), false);
|
||||
}
|
||||
|
||||
p.playSound(p.getLocation(), Sound.ENTITY_GENERIC_EAT, 1, 1);
|
||||
SoundEffect.MAGIC_SUGAR_CONSUME_SOUND.playFor(p);
|
||||
p.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, 600, 3));
|
||||
};
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem;
|
||||
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
|
||||
import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.listeners.BeeWingsListener;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.tasks.BeeWingsTask;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.tasks.player.BeeWingsTask;
|
||||
|
||||
/**
|
||||
* The {@link BeeWings} are a special form of the elytra which gives you a slow falling effect
|
||||
|
@ -5,8 +5,6 @@ import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.SoundCategory;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.data.type.Hopper;
|
||||
import org.bukkit.entity.Entity;
|
||||
@ -20,6 +18,7 @@ import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem;
|
||||
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
|
||||
import io.github.thebusybiscuit.slimefun4.api.items.settings.DoubleRangeSetting;
|
||||
import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
|
||||
import io.github.thebusybiscuit.slimefun4.core.services.sounds.SoundEffect;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.handlers.VanillaInventoryDropHandler;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
|
||||
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
|
||||
@ -55,7 +54,7 @@ public class InfusedHopper extends SimpleSlimefunItem<BlockTicker> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockTicker getItemHandler() {
|
||||
public @Nonnull BlockTicker getItemHandler() {
|
||||
return new BlockTicker() {
|
||||
|
||||
@Override
|
||||
@ -94,8 +93,8 @@ public class InfusedHopper extends SimpleSlimefunItem<BlockTicker> {
|
||||
* Play a sound if at least one item was teleported and
|
||||
* the "silent" setting is set to false.
|
||||
*/
|
||||
if (playSound && !silent.getValue().booleanValue()) {
|
||||
b.getWorld().playSound(b.getLocation(), Sound.ENTITY_ENDERMAN_TELEPORT, SoundCategory.BLOCKS, 1F, 2F);
|
||||
if (playSound && !silent.getValue()) {
|
||||
SoundEffect.INFUSED_HOPPER_TELEPORT_SOUND.playAt(b);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
package io.github.thebusybiscuit.slimefun4.implementation.items.magical;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
@ -12,6 +12,7 @@ import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem;
|
||||
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
|
||||
import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
|
||||
import io.github.thebusybiscuit.slimefun4.core.handlers.ItemUseHandler;
|
||||
import io.github.thebusybiscuit.slimefun4.core.services.sounds.SoundEffect;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
|
||||
|
||||
@ -30,11 +31,12 @@ public class KnowledgeFlask extends SimpleSlimefunItem<ItemUseHandler> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemUseHandler getItemHandler() {
|
||||
public @Nonnull ItemUseHandler getItemHandler() {
|
||||
return e -> {
|
||||
e.cancel();
|
||||
Player p = e.getPlayer();
|
||||
|
||||
if (p.getLevel() >= 1 && (!e.getClickedBlock().isPresent() || !(e.getClickedBlock().get().getType().isInteractable()))) {
|
||||
if (p.getLevel() >= 1 && (e.getClickedBlock().isEmpty() || !(e.getClickedBlock().get().getType().isInteractable()))) {
|
||||
p.setLevel(p.getLevel() - 1);
|
||||
|
||||
ItemStack item = SlimefunItems.FILLED_FLASK_OF_KNOWLEDGE.clone();
|
||||
@ -44,10 +46,8 @@ public class KnowledgeFlask extends SimpleSlimefunItem<ItemUseHandler> {
|
||||
p.getWorld().dropItemNaturally(p.getLocation(), item);
|
||||
}
|
||||
|
||||
p.playSound(p.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1F, 0.5F);
|
||||
|
||||
SoundEffect.FLASK_OF_KNOWLEDGE_FILLUP_SOUND.playFor(p);
|
||||
ItemUtils.consumeItem(e.getItem(), false);
|
||||
e.cancel();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -3,9 +3,11 @@ package io.github.thebusybiscuit.slimefun4.implementation.items.magical;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Event.Result;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
@ -19,17 +21,26 @@ import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile;
|
||||
import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
|
||||
import io.github.thebusybiscuit.slimefun4.api.researches.Research;
|
||||
import io.github.thebusybiscuit.slimefun4.core.handlers.ItemUseHandler;
|
||||
import io.github.thebusybiscuit.slimefun4.core.services.sounds.SoundEffect;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
|
||||
|
||||
/**
|
||||
* The {@link KnowledgeTome} allows you to copy every unlocked {@link Research}
|
||||
* from one {@link Player} to another.
|
||||
*
|
||||
* @author TheBusyBiscuit
|
||||
*
|
||||
*/
|
||||
public class KnowledgeTome extends SimpleSlimefunItem<ItemUseHandler> {
|
||||
|
||||
@ParametersAreNonnullByDefault
|
||||
public KnowledgeTome(ItemGroup itemGroup, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
||||
super(itemGroup, item, recipeType, recipe);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemUseHandler getItemHandler() {
|
||||
public @Nonnull ItemUseHandler getItemHandler() {
|
||||
return e -> {
|
||||
Player p = e.getPlayer();
|
||||
ItemStack item = e.getItem();
|
||||
@ -44,7 +55,7 @@ public class KnowledgeTome extends SimpleSlimefunItem<ItemUseHandler> {
|
||||
lore.set(1, ChatColor.BLACK + "" + p.getUniqueId());
|
||||
im.setLore(lore);
|
||||
item.setItemMeta(im);
|
||||
p.getWorld().playSound(p.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 1F, 1F);
|
||||
SoundEffect.TOME_OF_KNOWLEDGE_USE_SOUND.playFor(p);
|
||||
} else {
|
||||
UUID uuid = UUID.fromString(ChatColor.stripColor(item.getItemMeta().getLore().get(1)));
|
||||
|
||||
@ -65,5 +76,4 @@ public class KnowledgeTome extends SimpleSlimefunItem<ItemUseHandler> {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -3,7 +3,6 @@ package io.github.thebusybiscuit.slimefun4.implementation.items.magical;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.entity.EnderPearl;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
@ -13,6 +12,7 @@ import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup;
|
||||
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
|
||||
import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
|
||||
import io.github.thebusybiscuit.slimefun4.core.handlers.ItemUseHandler;
|
||||
import io.github.thebusybiscuit.slimefun4.core.services.sounds.SoundEffect;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
|
||||
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
|
||||
@ -32,7 +32,7 @@ public class MagicEyeOfEnder extends SimpleSlimefunItem<ItemUseHandler> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemUseHandler getItemHandler() {
|
||||
public @Nonnull ItemUseHandler getItemHandler() {
|
||||
return e -> {
|
||||
e.cancel();
|
||||
|
||||
@ -40,7 +40,7 @@ public class MagicEyeOfEnder extends SimpleSlimefunItem<ItemUseHandler> {
|
||||
|
||||
if (hasArmor(p.getInventory())) {
|
||||
p.launchProjectile(EnderPearl.class);
|
||||
p.getWorld().playSound(p.getLocation(), Sound.ENTITY_ENDERMAN_TELEPORT, 1, 1);
|
||||
SoundEffect.MAGICAL_EYE_OF_ENDER_USE_SOUND.playFor(p);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ public class MagicalZombiePills extends SimpleSlimefunItem<EntityInteractHandler
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityInteractHandler getItemHandler() {
|
||||
public @Nonnull EntityInteractHandler getItemHandler() {
|
||||
return (e, item, offhand) -> {
|
||||
Entity entity = e.getRightClicked();
|
||||
|
||||
@ -81,6 +81,7 @@ public class MagicalZombiePills extends SimpleSlimefunItem<EntityInteractHandler
|
||||
ItemUtils.consumeItem(item, false);
|
||||
}
|
||||
|
||||
// This is supposed to be a vanilla sound. No need for a SoundEffect
|
||||
p.playSound(p.getLocation(), Sound.ENTITY_ZOMBIE_VILLAGER_CONVERTED, 1, 1);
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,7 @@ import javax.annotation.ParametersAreNonnullByDefault;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Particle;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.SoundCategory;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Item;
|
||||
@ -27,6 +27,7 @@ import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem;
|
||||
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
|
||||
import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
|
||||
import io.github.thebusybiscuit.slimefun4.core.handlers.ItemDropHandler;
|
||||
import io.github.thebusybiscuit.slimefun4.core.services.sounds.SoundEffect;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
|
||||
|
||||
@ -140,7 +141,7 @@ public class EnchantmentRune extends SimpleSlimefunItem<ItemDropHandler> {
|
||||
if (rune.isValid() && item.isValid() && itemStack.getAmount() == 1) {
|
||||
|
||||
l.getWorld().spawnParticle(Particle.CRIT_MAGIC, l, 1);
|
||||
l.getWorld().playSound(l, Sound.ENTITY_ZOMBIE_VILLAGER_CURE, 1F, 1F);
|
||||
SoundEffect.ENCHANTMENT_RUNE_ADD_ENCHANT_SOUND.playAt(l, SoundCategory.PLAYERS);
|
||||
|
||||
item.remove();
|
||||
rune.remove();
|
||||
|
@ -7,7 +7,7 @@ import javax.annotation.Nonnull;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.SoundCategory;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Item;
|
||||
import org.bukkit.entity.Player;
|
||||
@ -19,6 +19,7 @@ import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
|
||||
import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
|
||||
import io.github.thebusybiscuit.slimefun4.core.attributes.Soulbound;
|
||||
import io.github.thebusybiscuit.slimefun4.core.handlers.ItemDropHandler;
|
||||
import io.github.thebusybiscuit.slimefun4.core.services.sounds.SoundEffect;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.items.magical.SoulboundItem;
|
||||
@ -46,7 +47,7 @@ public class SoulboundRune extends SimpleSlimefunItem<ItemDropHandler> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemDropHandler getItemHandler() {
|
||||
public @Nonnull ItemDropHandler getItemHandler() {
|
||||
return (e, p, item) -> {
|
||||
if (isItem(item.getItemStack())) {
|
||||
|
||||
@ -85,7 +86,7 @@ public class SoulboundRune extends SimpleSlimefunItem<ItemDropHandler> {
|
||||
if (rune.isValid() && item.isValid() && itemStack.getAmount() == 1) {
|
||||
|
||||
l.getWorld().createExplosion(l, 0);
|
||||
l.getWorld().playSound(l, Sound.ENTITY_GENERIC_EXPLODE, 0.3F, 1);
|
||||
SoundEffect.SOULBOUND_RUNE_RITUAL_SOUND.playAt(l, SoundCategory.PLAYERS);
|
||||
|
||||
item.remove();
|
||||
rune.remove();
|
||||
@ -115,13 +116,10 @@ public class SoulboundRune extends SimpleSlimefunItem<ItemDropHandler> {
|
||||
* @return Whether this {@link Entity} is compatible
|
||||
*/
|
||||
private boolean findCompatibleItem(@Nonnull Entity entity) {
|
||||
if (entity instanceof Item) {
|
||||
Item item = (Item) entity;
|
||||
|
||||
return !SlimefunUtils.isSoulbound(item.getItemStack()) && !isItem(item.getItemStack());
|
||||
if (entity instanceof Item item) {
|
||||
return item.getPickupDelay() <= 0 && !SlimefunUtils.isSoulbound(item.getItemStack()) && !isItem(item.getItemStack());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,11 +2,12 @@ package io.github.thebusybiscuit.slimefun4.implementation.items.magical.runes;
|
||||
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Particle;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.SoundCategory;
|
||||
import org.bukkit.entity.Villager;
|
||||
import org.bukkit.entity.Villager.Profession;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
@ -18,6 +19,7 @@ import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem;
|
||||
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
|
||||
import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
|
||||
import io.github.thebusybiscuit.slimefun4.core.handlers.EntityInteractHandler;
|
||||
import io.github.thebusybiscuit.slimefun4.core.services.sounds.SoundEffect;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
|
||||
|
||||
@ -36,7 +38,7 @@ public class VillagerRune extends SimpleSlimefunItem<EntityInteractHandler> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityInteractHandler getItemHandler() {
|
||||
public @Nonnull EntityInteractHandler getItemHandler() {
|
||||
return (e, item, offhand) -> {
|
||||
if (e.isCancelled() || !Slimefun.getProtectionManager().hasPermission(e.getPlayer(), e.getRightClicked().getLocation(), Interaction.INTERACT_ENTITY)) {
|
||||
// They don't have permission to use it in this area
|
||||
@ -60,7 +62,7 @@ public class VillagerRune extends SimpleSlimefunItem<EntityInteractHandler> {
|
||||
|
||||
double offset = ThreadLocalRandom.current().nextDouble(0.5);
|
||||
|
||||
villager.getWorld().playSound(villager.getLocation(), Sound.ENTITY_VILLAGER_CELEBRATE, 1, 1.4F);
|
||||
SoundEffect.VILLAGER_RUNE_TRANSFORM_SOUND.playAt(villager.getLocation(), SoundCategory.NEUTRAL);
|
||||
villager.getWorld().spawnParticle(Particle.CRIMSON_SPORE, villager.getLocation(), 10, 0, offset / 2, 0, 0);
|
||||
villager.getWorld().spawnParticle(Particle.ENCHANTMENT_TABLE, villager.getLocation(), 5, 0.04, 1, 0.04);
|
||||
}
|
||||
|
@ -1,11 +1,11 @@
|
||||
package io.github.thebusybiscuit.slimefun4.implementation.items.magical.staves;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Effect;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.entity.FoodLevelChangeEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
@ -16,6 +16,7 @@ import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
|
||||
import io.github.thebusybiscuit.slimefun4.api.items.settings.IntRangeSetting;
|
||||
import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
|
||||
import io.github.thebusybiscuit.slimefun4.core.handlers.ItemUseHandler;
|
||||
import io.github.thebusybiscuit.slimefun4.core.services.sounds.SoundEffect;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
|
||||
|
||||
@ -37,7 +38,7 @@ public class WindStaff extends SimpleSlimefunItem<ItemUseHandler> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemUseHandler getItemHandler() {
|
||||
public @Nonnull ItemUseHandler getItemHandler() {
|
||||
return e -> {
|
||||
Player p = e.getPlayer();
|
||||
|
||||
@ -53,7 +54,7 @@ public class WindStaff extends SimpleSlimefunItem<ItemUseHandler> {
|
||||
}
|
||||
|
||||
p.setVelocity(p.getEyeLocation().getDirection().multiply(multiplier.getValue()));
|
||||
p.getWorld().playSound(p.getLocation(), Sound.ENTITY_TNT_PRIMED, 1, 1);
|
||||
SoundEffect.WIND_STAFF_USE_SOUND.playFor(p);
|
||||
p.getWorld().playEffect(p.getLocation(), Effect.SMOKE, 1);
|
||||
p.setFallDistance(0F);
|
||||
} else {
|
||||
@ -61,5 +62,4 @@ public class WindStaff extends SimpleSlimefunItem<ItemUseHandler> {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup;
|
||||
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
|
||||
import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
|
||||
import io.github.thebusybiscuit.slimefun4.core.handlers.ItemConsumptionHandler;
|
||||
import io.github.thebusybiscuit.slimefun4.utils.RadiationUtils;
|
||||
|
||||
public class Medicine extends MedicalSupply<ItemConsumptionHandler> {
|
||||
|
||||
@ -21,6 +22,7 @@ public class Medicine extends MedicalSupply<ItemConsumptionHandler> {
|
||||
return (e, p, item) -> {
|
||||
p.setFireTicks(0);
|
||||
clearNegativeEffects(p);
|
||||
RadiationUtils.clearExposure(p);
|
||||
heal(p);
|
||||
};
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
package io.github.thebusybiscuit.slimefun4.implementation.items.medical;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.attribute.Attribute;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
@ -15,6 +15,7 @@ import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup;
|
||||
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
|
||||
import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
|
||||
import io.github.thebusybiscuit.slimefun4.core.handlers.ItemUseHandler;
|
||||
import io.github.thebusybiscuit.slimefun4.core.services.sounds.SoundEffect;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
|
||||
|
||||
public class Splint extends SimpleSlimefunItem<ItemUseHandler> {
|
||||
@ -25,7 +26,7 @@ public class Splint extends SimpleSlimefunItem<ItemUseHandler> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemUseHandler getItemHandler() {
|
||||
public @Nonnull ItemUseHandler getItemHandler() {
|
||||
return e -> {
|
||||
Player p = e.getPlayer();
|
||||
|
||||
@ -38,11 +39,10 @@ public class Splint extends SimpleSlimefunItem<ItemUseHandler> {
|
||||
ItemUtils.consumeItem(e.getItem(), false);
|
||||
}
|
||||
|
||||
p.getWorld().playSound(p.getLocation(), Sound.ENTITY_SKELETON_HURT, 1, 1);
|
||||
SoundEffect.SPLINT_CONSUME_SOUND.playFor(p);
|
||||
p.addPotionEffect(new PotionEffect(PotionEffectType.HEAL, 1, 0));
|
||||
|
||||
e.cancel();
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
package io.github.thebusybiscuit.slimefun4.implementation.items.medical;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
@ -12,6 +12,8 @@ import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup;
|
||||
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
|
||||
import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
|
||||
import io.github.thebusybiscuit.slimefun4.core.handlers.ItemUseHandler;
|
||||
import io.github.thebusybiscuit.slimefun4.core.services.sounds.SoundEffect;
|
||||
import io.github.thebusybiscuit.slimefun4.utils.RadiationUtils;
|
||||
|
||||
public class Vitamins extends MedicalSupply<ItemUseHandler> {
|
||||
|
||||
@ -21,10 +23,10 @@ public class Vitamins extends MedicalSupply<ItemUseHandler> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemUseHandler getItemHandler() {
|
||||
public @Nonnull ItemUseHandler getItemHandler() {
|
||||
return e -> {
|
||||
Player p = e.getPlayer();
|
||||
p.getWorld().playSound(p.getLocation(), Sound.ENTITY_GENERIC_EAT, 1, 1);
|
||||
SoundEffect.VITAMINS_CONSUME_SOUND.playFor(p);
|
||||
|
||||
if (p.getGameMode() != GameMode.CREATIVE) {
|
||||
ItemUtils.consumeItem(e.getItem(), false);
|
||||
@ -33,8 +35,8 @@ public class Vitamins extends MedicalSupply<ItemUseHandler> {
|
||||
e.cancel();
|
||||
p.setFireTicks(0);
|
||||
clearNegativeEffects(p);
|
||||
RadiationUtils.clearExposure(p);
|
||||
heal(p);
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user