1
mirror of https://github.com/StarWishsama/Slimefun4.git synced 2024-09-20 11:45:51 +00:00

Merge branch 'master' into feature/adds-suggestion-242

This commit is contained in:
J3fftw 2022-10-10 12:43:58 +02:00 committed by GitHub
commit 41653f5766
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
221 changed files with 2126 additions and 1003 deletions

View File

@ -17,6 +17,7 @@
<!-- Don't worry, these are not requirements. They only serve as guidance. --> <!-- 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 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 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.14.* - 1.19.*).
- [ ] I followed the existing code standards and didn't mess up the formatting. - [ ] 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 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 - [ ] I have added `Nonnull` and `Nullable` annotations to my methods to indicate their behaviour for null values

View File

@ -2,18 +2,25 @@ name: Auto approve
on: pull_request on: pull_request
permissions:
contents: read
jobs: jobs:
auto-approve: auto-approve:
name: Auto approve Pull Request name: Auto approve Pull Request
runs-on: ubuntu-latest runs-on: ubuntu-latest
## Only run this on the main repo # for hmarr/auto-approve-action to approve PRs
permissions:
pull-requests: write
# Only run this on the main repo
if: github.event.pull_request.head.repo.full_name == 'Slimefun/Slimefun4' if: github.event.pull_request.head.repo.full_name == 'Slimefun/Slimefun4'
steps: steps:
- name: Approve via actions - name: Approve via actions
uses: hmarr/auto-approve-action@v2.2.1 uses: hmarr/auto-approve-action@v2.4.0
if: github.actor == 'TheBusyBot' || github.actor == 'renovate[bot]' if: github.actor == 'TheBusyBot' || github.actor == 'renovate[bot]'
with: with:
github-token: "${{ secrets.GITHUB_TOKEN }}" github-token: "${{ secrets.GITHUB_TOKEN }}"

View File

@ -7,6 +7,9 @@ on:
- '!src/main/resources/languages/**' - '!src/main/resources/languages/**'
- 'pom.xml' - 'pom.xml'
permissions:
contents: read
jobs: jobs:
report: report:
@ -18,10 +21,10 @@ jobs:
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v3.0.2 uses: actions/checkout@v3.1.0
- name: Set up Java JDK 17 - name: Set up Java JDK 17
uses: actions/setup-java@v3.3.0 uses: actions/setup-java@v3.5.1
with: with:
distribution: 'adopt' distribution: 'adopt'
java-version: '17' java-version: '17'

View File

@ -4,6 +4,10 @@ on:
issue_comment: issue_comment:
types: [created] types: [created]
permissions:
contents: read
issues: write
jobs: jobs:
comment: comment:

View File

@ -8,6 +8,9 @@ on:
paths: paths:
- 'src/main/resources/wiki.json' - 'src/main/resources/wiki.json'
permissions:
contents: read
jobs: jobs:
validate: validate:

View File

@ -4,6 +4,10 @@ on:
issues: issues:
types: [closed] types: [closed]
permissions:
contents: read
issues: write
jobs: jobs:
label: label:

View File

@ -13,6 +13,9 @@ on:
- 'src/**' - 'src/**'
- 'pom.xml' - 'pom.xml'
permissions:
contents: read
jobs: jobs:
build: build:
@ -24,7 +27,7 @@ jobs:
uses: actions/checkout@v3 uses: actions/checkout@v3
- name: Set up JDK 17 - name: Set up JDK 17
uses: actions/setup-java@v3.3.0 uses: actions/setup-java@v3.5.1
with: with:
distribution: 'adopt' distribution: 'adopt'
java-version: '17' java-version: '17'

View File

@ -5,6 +5,10 @@ on:
branches: branches:
- master - master
permissions:
contents: read
pull-requests: write
jobs: jobs:
validate: validate:

View File

@ -5,6 +5,10 @@ on:
types: types:
- opened - opened
permissions:
contents: read
pull-requests: write
jobs: jobs:
pr-labeler: pr-labeler:

View File

@ -4,6 +4,9 @@ on:
pull_request: pull_request:
types: [opened, synchronize, reopened] types: [opened, synchronize, reopened]
permissions:
contents: read
jobs: jobs:
scan: scan:
@ -16,12 +19,12 @@ jobs:
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v3.0.2 uses: actions/checkout@v3.1.0
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Set up JDK 17 - name: Set up JDK 17
uses: actions/setup-java@v3.3.0 uses: actions/setup-java@v3.5.1
with: with:
distribution: 'adopt' distribution: 'adopt'
java-version: '17' java-version: '17'

View File

@ -7,6 +7,9 @@ on:
paths: paths:
- 'src/main/resources/languages/en/**.yml' - 'src/main/resources/languages/en/**.yml'
permissions:
contents: read
jobs: jobs:
notify: notify:

View File

@ -8,6 +8,9 @@ on:
branches: branches:
- master - master
permissions:
contents: read
jobs: jobs:
linter: linter:

1
.gitignore vendored
View File

@ -12,4 +12,5 @@ dependency-reduced-pom.xml
.factorypath .factorypath
.project .project
*.iml *.iml
*.bak
.DS_Store .DS_Store

View File

@ -1,5 +1,6 @@
# Table of contents # Table of contents
- [Release Candidate 32 (TBD)](#release-candidate-32-tbd) - [Release Candidate 33 (TBD)](#release-candidate-33-tbd)
- [Release Candidate 32 (26 Jun 2022)](#release-candidate-32-26-jun-2022)
- [Release Candidate 31 (14 Mar 2022)](#release-candidate-31-14-mar-2022) - [Release Candidate 31 (14 Mar 2022)](#release-candidate-31-14-mar-2022)
- [Release Candidate 30 (31 Dec 2021)](#release-candidate-30-31-dec-2021) - [Release Candidate 30 (31 Dec 2021)](#release-candidate-30-31-dec-2021)
- [Release Candidate 29 (07 Nov 2021)](#release-candidate-29-07-nov-2021) - [Release Candidate 29 (07 Nov 2021)](#release-candidate-29-07-nov-2021)
@ -33,7 +34,38 @@
- [Release Candidate 1 (26 Sep 2019)](#release-candidate-1-26-sep-2019) - [Release Candidate 1 (26 Sep 2019)](#release-candidate-1-26-sep-2019)
## Release Candidate 32 (TBD) ## Release Candidate 33 (TBD)
#### Additions
* (API) Added Tinted Glass to "GLASS_BLOCKS" tag
* (API) Added "WOOL_CARPETS" tag (for compatibility across MC 1.19/1.18 tags)
* Added a new language: Persian
* Added a new language: Romanian
* (API) Added a method for item groups to allow addons to choose if they want to allow items from other addons
* Added a new option to Eletric Gold Pans: "override-output-limit"
* Added "Mud -> Clay" recipe to the Auto Drier
* Added a third tier for Freezers
* Added Glow Berry Juice
#### Changes
* Tree Growth Accelerators can now actually cause the Tree to fully grow (1.17+ only)
* Slimefun now requires Java 16
* "Connected / Not connected" messages for cargo nodes are now sent via the actionbar
* "/sf stats" can no longer be used if researching is disabled
* "/sf research" can no longer be used if researching is disabled
* Removed the Hercules Pickaxe from Slimefun
#### Fixes
* Fixed #3597
* Fixed an issue related to "Bee Wings"
* Fixed #3573
* Fixed "round-robin" mode for cargo networks being very unreliable
* Fixed #3664
* Fixed #3651
* Fixed #3677
## Release Candidate 32 (26 Jun 2022)
https://thebusybiscuit.github.io/builds/TheBusyBiscuit/Slimefun4/stable/#32
#### Additions #### Additions
* Added Organic Food for Seagrass * Added Organic Food for Seagrass

View File

@ -30,7 +30,8 @@ Here is a full summary of the differences between the two different versions of
| | development (latest) | "stable" | | | development (latest) | "stable" |
| ------------------ | -------- | -------- | | ------------------ | -------- | -------- |
| **Minecraft version(s)** | :video_game: **1.14.\* - 1.19.\*** | :video_game: **1.14.\* - 1.18.\*** | | **Minecraft version(s)** | :video_game: **1.14.\* - 1.19.\*** | :video_game: **1.14.\* - 1.19.\*** |
| **Java version** | :computer: **Java 16 (or higher)** | :computer: **Java 8 (or higher)** |
| **automatic updates** | :heavy_check_mark: | :heavy_check_mark: | | **automatic updates** | :heavy_check_mark: | :heavy_check_mark: |
| **frequent updates** | :heavy_check_mark: | :x: | | **frequent updates** | :heavy_check_mark: | :x: |
| **latest content** | :heavy_check_mark: | :x: | | **latest content** | :heavy_check_mark: | :x: |

28
pom.xml
View File

@ -21,9 +21,9 @@
<!-- UTF-8 is our standard encoding for source files --> <!-- UTF-8 is our standard encoding for source files -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- Target Java 8 --> <!-- Target Java 16 -->
<maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.source>16</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target> <maven.compiler.target>16</maven.compiler.target>
<!-- Spigot properties --> <!-- Spigot properties -->
<spigot.version>1.19</spigot.version> <spigot.version>1.19</spigot.version>
@ -191,7 +191,7 @@
<!-- Dependency shading --> <!-- Dependency shading -->
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId> <artifactId>maven-shade-plugin</artifactId>
<version>3.3.0</version> <version>3.4.0</version>
<configuration> <configuration>
<!-- Relocate these to avoid clashes and conflicts --> <!-- Relocate these to avoid clashes and conflicts -->
@ -239,7 +239,7 @@
<!-- Javadocs --> <!-- Javadocs -->
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId> <artifactId>maven-javadoc-plugin</artifactId>
<version>3.4.0</version> <version>3.4.1</version>
<configuration> <configuration>
<reportOutputDirectory>${project.basedir}</reportOutputDirectory> <reportOutputDirectory>${project.basedir}</reportOutputDirectory>
@ -366,7 +366,7 @@
<dependency> <dependency>
<groupId>com.konghq</groupId> <groupId>com.konghq</groupId>
<artifactId>unirest-java</artifactId> <artifactId>unirest-java</artifactId>
<version>3.13.8</version> <version>3.13.11</version>
<scope>compile</scope> <scope>compile</scope>
<exclusions> <exclusions>
@ -382,13 +382,13 @@
<dependency> <dependency>
<groupId>org.junit.jupiter</groupId> <groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId> <artifactId>junit-jupiter</artifactId>
<version>5.8.2</version> <version>5.9.1</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.mockito</groupId> <groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId> <artifactId>mockito-core</artifactId>
<version>4.6.1</version> <version>4.8.0</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency> <dependency>
@ -411,7 +411,7 @@
<dependency> <dependency>
<groupId>com.sk89q.worldedit</groupId> <groupId>com.sk89q.worldedit</groupId>
<artifactId>worldedit-core</artifactId> <artifactId>worldedit-core</artifactId>
<version>7.2.10</version> <version>7.2.12</version>
<scope>provided</scope> <scope>provided</scope>
<exclusions> <exclusions>
@ -425,7 +425,7 @@
<dependency> <dependency>
<groupId>com.sk89q.worldedit</groupId> <groupId>com.sk89q.worldedit</groupId>
<artifactId>worldedit-bukkit</artifactId> <artifactId>worldedit-bukkit</artifactId>
<version>7.2.10</version> <version>7.2.12</version>
<scope>provided</scope> <scope>provided</scope>
<exclusions> <exclusions>
@ -439,7 +439,7 @@
<dependency> <dependency>
<groupId>com.gmail.nossr50.mcMMO</groupId> <groupId>com.gmail.nossr50.mcMMO</groupId>
<artifactId>mcMMO</artifactId> <artifactId>mcMMO</artifactId>
<version>2.1.214</version> <version>2.1.217</version>
<scope>provided</scope> <scope>provided</scope>
<exclusions> <exclusions>
@ -453,7 +453,7 @@
<dependency> <dependency>
<groupId>me.clip</groupId> <groupId>me.clip</groupId>
<artifactId>placeholderapi</artifactId> <artifactId>placeholderapi</artifactId>
<version>2.11.1</version> <version>2.11.2</version>
<scope>provided</scope> <scope>provided</scope>
<exclusions> <exclusions>
@ -481,7 +481,7 @@
<dependency> <dependency>
<groupId>com.github.LoneDev6</groupId> <groupId>com.github.LoneDev6</groupId>
<artifactId>itemsadder-api</artifactId> <artifactId>itemsadder-api</artifactId>
<version>3.1.6</version> <version>3.2.3-r8</version>
<scope>provided</scope> <scope>provided</scope>
<exclusions> <exclusions>
@ -495,7 +495,7 @@
<dependency> <dependency>
<groupId>net.imprex</groupId> <groupId>net.imprex</groupId>
<artifactId>orebfuscator-api</artifactId> <artifactId>orebfuscator-api</artifactId>
<version>5.2.6</version> <version>5.3.0</version>
<scope>provided</scope> <scope>provided</scope>
<exclusions> <exclusions>

View File

@ -8,6 +8,7 @@ import java.util.Set;
import java.util.UUID; import java.util.UUID;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.ParametersAreNonnullByDefault;
import org.apache.commons.lang.Validate; import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
@ -57,6 +58,7 @@ public class GPSNetwork {
private final Map<UUID, Set<Location>> transmitters = new HashMap<>(); private final Map<UUID, Set<Location>> transmitters = new HashMap<>();
private final TeleportationManager teleportation = new TeleportationManager(); private final TeleportationManager teleportation = new TeleportationManager();
private final ResourceManager resourceManager; private final ResourceManager resourceManager;
/** /**
@ -111,8 +113,8 @@ public class GPSNetwork {
for (Location l : locations) { for (Location l : locations) {
SlimefunItem item = BlockStorage.check(l); SlimefunItem item = BlockStorage.check(l);
if (item instanceof GPSTransmitter) { if (item instanceof GPSTransmitter transmitter) {
level += ((GPSTransmitter) item).getMultiplier(Math.max(l.getBlockY(), 0)); level += transmitter.getMultiplier(Math.max(l.getBlockY(), 0));
} }
} }
@ -155,7 +157,7 @@ public class GPSNetwork {
menu.addMenuClickHandler(2, ChestMenuUtils.getEmptyClickHandler()); menu.addMenuClickHandler(2, ChestMenuUtils.getEmptyClickHandler());
int complexity = getNetworkComplexity(p.getUniqueId()); int complexity = getNetworkComplexity(p.getUniqueId());
menu.addItem(4, new CustomItemStack(SlimefunItems.GPS_CONTROL_PANEL, "&7Network Info", "", "&8\u21E8 &7Status: " + (complexity > 0 ? "&2&lONLINE" : "&4&lOFFLINE"), "&8\u21E8 &7Complexity: &f" + complexity)); menu.addItem(4, new CustomItemStack(SlimefunItems.GPS_CONTROL_PANEL, "&7Network Info", "", "&8\u21E8 &7Status: " + getStatusText(p, complexity), "&8\u21E8 &7Complexity: &f" + complexity));
menu.addMenuClickHandler(4, ChestMenuUtils.getEmptyClickHandler()); menu.addMenuClickHandler(4, ChestMenuUtils.getEmptyClickHandler());
menu.addItem(6, new CustomItemStack(HeadTexture.GLOBE_OVERWORLD.getAsItemStack(), "&7" + Slimefun.getLocalization().getMessage(p, "machines.GPS_CONTROL_PANEL.waypoints"), "", ChatColor.GRAY + "\u21E8 " + Slimefun.getLocalization().getMessage(p, "guide.tooltips.open-itemgroup"))); menu.addItem(6, new CustomItemStack(HeadTexture.GLOBE_OVERWORLD.getAsItemStack(), "&7" + Slimefun.getLocalization().getMessage(p, "machines.GPS_CONTROL_PANEL.waypoints"), "", ChatColor.GRAY + "\u21E8 " + Slimefun.getLocalization().getMessage(p, "guide.tooltips.open-itemgroup")));
@ -172,10 +174,10 @@ public class GPSNetwork {
SlimefunItem sfi = BlockStorage.check(l); SlimefunItem sfi = BlockStorage.check(l);
if (sfi instanceof GPSTransmitter) { if (sfi instanceof GPSTransmitter transmitter) {
int slot = inventory[index]; int slot = inventory[index];
menu.addItem(slot, new CustomItemStack(SlimefunItems.GPS_TRANSMITTER, "&bGPS Transmitter", "&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 &7Signal Strength: &f" + ((GPSTransmitter) sfi).getMultiplier(l.getBlockY()), "&8\u21E8 &7Ping: &f" + NumberUtils.roundDecimalNumber(1000D / l.getY()) + "ms")); menu.addItem(slot, new CustomItemStack(SlimefunItems.GPS_TRANSMITTER, "&bGPS Transmitter", "&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 &7Signal Strength: &f" + transmitter.getMultiplier(l.getBlockY()), "&8\u21E8 &7Ping: &f" + NumberUtils.roundDecimalNumber(1000D / l.getY()) + "ms"));
menu.addMenuClickHandler(slot, ChestMenuUtils.getEmptyClickHandler()); menu.addMenuClickHandler(slot, ChestMenuUtils.getEmptyClickHandler());
index++; index++;
@ -200,8 +202,8 @@ public class GPSNetwork {
* *
* @return An icon for this waypoint * @return An icon for this waypoint
*/ */
@Nonnull @ParametersAreNonnullByDefault
public ItemStack getIcon(@Nonnull String name, @Nonnull Environment environment) { public @Nonnull ItemStack getIcon(String name, Environment environment) {
if (name.startsWith("player:death ")) { if (name.startsWith("player:death ")) {
return HeadTexture.DEATHPOINT.getAsItemStack(); return HeadTexture.DEATHPOINT.getAsItemStack();
} else if (environment == Environment.NETHER) { } else if (environment == Environment.NETHER) {
@ -213,6 +215,15 @@ public class GPSNetwork {
} }
} }
@ParametersAreNonnullByDefault
private @Nonnull String getStatusText(Player player, int complexity) {
if (complexity > 0) {
return "&2&l" + Slimefun.getLocalization().getMessage(player, "gps.status-online");
} else {
return "&4&l" + Slimefun.getLocalization().getMessage(player, "gps.status-offline");
}
}
public void openWaypointControlPanel(@Nonnull Player p) { public void openWaypointControlPanel(@Nonnull Player p) {
PlayerProfile.get(p, profile -> { PlayerProfile.get(p, profile -> {
ChestMenu menu = new ChestMenu(ChatColor.BLUE + Slimefun.getLocalization().getMessage(p, "machines.GPS_CONTROL_PANEL.title")); ChestMenu menu = new ChestMenu(ChatColor.BLUE + Slimefun.getLocalization().getMessage(p, "machines.GPS_CONTROL_PANEL.title"));

View File

@ -128,7 +128,8 @@ public final class TeleportationManager {
teleporterUsers.add(uuid); teleporterUsers.add(uuid);
int time = getTeleportationTime(complexity, source, destination); int time = getTeleportationTime(complexity, source, destination);
updateProgress(uuid, Math.max(1, 100 / time), 0, source, destination, resistance); int speed = Math.max(1, 100 / time);
updateProgress(uuid, speed, 0, source, destination, resistance);
} }
/** /**
@ -162,7 +163,10 @@ public final class TeleportationManager {
} }
int speed = 50_000 + complexity * complexity; int speed = 50_000 + complexity * complexity;
return 1 + Math.min(4 * distanceSquared(source, destination) / speed, 40); int unsafeTime = Math.min(4 * distanceSquared(source, destination) / speed, 40);
// Fixes #3573 - Using Math.max is a safer way to ensure values > 0 than relying on addition.
return Math.max(1, unsafeTime);
} }
@ParametersAreNonnullByDefault @ParametersAreNonnullByDefault

View File

@ -61,8 +61,8 @@ public final class HashedArmorpiece {
this.hash = copy.hashCode(); this.hash = copy.hashCode();
} }
if (item instanceof SlimefunArmorPiece) { if (item instanceof SlimefunArmorPiece armorPiece) {
this.item = Optional.of((SlimefunArmorPiece) item); this.item = Optional.of(armorPiece);
} else { } else {
this.item = Optional.empty(); this.item = Optional.empty();
} }

View File

@ -44,6 +44,7 @@ public class ItemGroup implements Keyed {
protected final NamespacedKey key; protected final NamespacedKey key;
protected final ItemStack item; protected final ItemStack item;
protected int tier; protected int tier;
protected boolean crossAddonItemGroup = false;
/** /**
* Constructs a new {@link ItemGroup} with the given {@link NamespacedKey} as an identifier * Constructs a new {@link ItemGroup} with the given {@link NamespacedKey} as an identifier
@ -184,7 +185,7 @@ public class ItemGroup implements Keyed {
return; return;
} }
if (isRegistered() && !item.getAddon().getName().equals(this.addon.getName())) { if (isRegistered() && !isCrossAddonItemGroup() && !item.getAddon().getName().equals(this.addon.getName())) {
item.warn("This item does not belong into ItemGroup " + this + " as that group belongs to " + this.addon.getName()); item.warn("This item does not belong into ItemGroup " + this + " as that group belongs to " + this.addon.getName());
} }
@ -325,10 +326,33 @@ public class ItemGroup implements Keyed {
return false; return false;
} }
/**
* Returns if items from other addons are allowed to be
* added to this {@link ItemGroup}.
*
* @return true if items from other addons are allowed to be added to this {@link ItemGroup}.
*/
public boolean isCrossAddonItemGroup() {
return crossAddonItemGroup;
}
/**
* This method will set if this {@link ItemGroup} will
* allow {@link SlimefunItem}s from other addons to
* be added, without a warning, into the group. False by default.
* If set to true, Slimefun will not warn about items being added.
*
* @param crossAddonItemGroup
* Whether items from another addon are allowable
*/
public void setCrossAddonItemGroup(boolean crossAddonItemGroup) {
this.crossAddonItemGroup = crossAddonItemGroup;
}
@Override @Override
public final boolean equals(Object obj) { public final boolean equals(Object obj) {
if (obj instanceof ItemGroup) { if (obj instanceof ItemGroup group) {
return ((ItemGroup) obj).getKey().equals(getKey()); return group.getKey().equals(this.getKey());
} else { } else {
return false; return false;
} }

View File

@ -482,8 +482,8 @@ public class SlimefunItem implements Placeable {
} }
// Lock the SlimefunItemStack from any accidental manipulations // Lock the SlimefunItemStack from any accidental manipulations
if (itemStackTemplate instanceof SlimefunItemStack && isItemStackImmutable()) { if (itemStackTemplate instanceof SlimefunItemStack stack && isItemStackImmutable()) {
((SlimefunItemStack) itemStackTemplate).lock(); stack.lock();
} }
postRegister(); postRegister();
@ -755,8 +755,8 @@ public class SlimefunItem implements Placeable {
} }
// If the given item is a SlimefunitemStack, simply compare the id // If the given item is a SlimefunitemStack, simply compare the id
if (item instanceof SlimefunItemStack) { if (item instanceof SlimefunItemStack stack) {
return getId().equals(((SlimefunItemStack) item).getItemId()); return getId().equals(stack.getItemId());
} }
if (item.hasItemMeta()) { if (item.hasItemMeta()) {
@ -807,10 +807,10 @@ public class SlimefunItem implements Placeable {
itemhandlers.put(handler.getIdentifier(), handler); itemhandlers.put(handler.getIdentifier(), handler);
// Tickers are a special case (at the moment at least) // Tickers are a special case (at the moment at least)
if (handler instanceof BlockTicker) { if (handler instanceof BlockTicker ticker) {
ticking = true; ticking = true;
Slimefun.getRegistry().getTickerBlocks().add(getId()); Slimefun.getRegistry().getTickerBlocks().add(getId());
blockTicker = (BlockTicker) handler; blockTicker = ticker;
} }
} }
} }
@ -985,7 +985,8 @@ public class SlimefunItem implements Placeable {
* @param message * @param message
* The message to send * The message to send
*/ */
public void info(@Nonnull String message) { @ParametersAreNonnullByDefault
public void info(String message) {
Validate.notNull(addon, "Cannot log a message for an unregistered item!"); Validate.notNull(addon, "Cannot log a message for an unregistered item!");
String msg = toString() + ": " + message; String msg = toString() + ": " + message;
@ -1000,7 +1001,8 @@ public class SlimefunItem implements Placeable {
* @param message * @param message
* The message to send * The message to send
*/ */
public void warn(@Nonnull String message) { @ParametersAreNonnullByDefault
public void warn(String message) {
Validate.notNull(addon, "Cannot send a warning for an unregistered item!"); Validate.notNull(addon, "Cannot send a warning for an unregistered item!");
String msg = toString() + ": " + message; String msg = toString() + ": " + message;
@ -1021,7 +1023,8 @@ public class SlimefunItem implements Placeable {
* @param throwable * @param throwable
* The {@link Throwable} to throw as a stacktrace. * The {@link Throwable} to throw as a stacktrace.
*/ */
public void error(@Nonnull String message, @Nonnull Throwable throwable) { @ParametersAreNonnullByDefault
public void error(String message, Throwable throwable) {
Validate.notNull(addon, "Cannot send an error for an unregistered item!"); Validate.notNull(addon, "Cannot send an error for an unregistered item!");
addon.getLogger().log(Level.SEVERE, "Item \"{0}\" from {1} v{2} has caused an Error!", new Object[] { id, addon.getName(), addon.getPluginVersion() }); addon.getLogger().log(Level.SEVERE, "Item \"{0}\" from {1} v{2} has caused an Error!", new Object[] { id, addon.getName(), addon.getPluginVersion() });
@ -1033,11 +1036,24 @@ public class SlimefunItem implements Placeable {
addon.getLogger().log(Level.SEVERE, message, throwable); addon.getLogger().log(Level.SEVERE, message, throwable);
// We definitely want to re-throw them during Unit Tests // We definitely want to re-throw them during Unit Tests
if (throwable instanceof RuntimeException && Slimefun.getMinecraftVersion() == MinecraftVersion.UNIT_TEST) { if (throwable instanceof RuntimeException e && Slimefun.getMinecraftVersion() == MinecraftVersion.UNIT_TEST) {
throw (RuntimeException) throwable; throw e;
} }
} }
/**
* This method informs the given {@link Player} that this {@link SlimefunItem}
* will be removed soon.
*
* @param player
* The {@link Player} to inform.
*/
@ParametersAreNonnullByDefault
public void sendDeprecationWarning(Player player) {
Validate.notNull(player, "The Player must not be null.");
Slimefun.getLocalization().sendMessage(player, "messages.deprecated-item");
}
/** /**
* This method checks if the given {@link Player} is able to use this {@link SlimefunItem}. * This method checks if the given {@link Player} is able to use this {@link SlimefunItem}.
* A {@link Player} can use it if the following conditions apply: * A {@link Player} can use it if the following conditions apply:
@ -1122,8 +1138,8 @@ public class SlimefunItem implements Placeable {
@Override @Override
public final boolean equals(Object obj) { public final boolean equals(Object obj) {
if (obj instanceof SlimefunItem) { if (obj instanceof SlimefunItem item) {
return ((SlimefunItem) obj).getId().equals(getId()); return item.getId().equals(this.getId());
} else { } else {
return false; return false;
} }
@ -1157,8 +1173,8 @@ public class SlimefunItem implements Placeable {
return null; return null;
} }
if (item instanceof SlimefunItemStack) { if (item instanceof SlimefunItemStack stack) {
return getById(((SlimefunItemStack) item).getItemId()); return getById(stack.getItemId());
} }
Optional<String> itemID = Slimefun.getItemDataService().getItemData(item); Optional<String> itemID = Slimefun.getItemDataService().getItemData(item);

View File

@ -128,12 +128,12 @@ public class SlimefunItemStack extends ItemStack {
im.setLore(lines); im.setLore(lines);
} }
if (im instanceof LeatherArmorMeta) { if (im instanceof LeatherArmorMeta leatherArmorMeta) {
((LeatherArmorMeta) im).setColor(color); leatherArmorMeta.setColor(color);
} }
if (im instanceof PotionMeta) { if (im instanceof PotionMeta potionMeta) {
((PotionMeta) im).setColor(color); potionMeta.setColor(color);
} }
}); });
} }
@ -154,9 +154,9 @@ public class SlimefunItemStack extends ItemStack {
im.setLore(lines); im.setLore(lines);
} }
if (im instanceof PotionMeta) { if (im instanceof PotionMeta potionMeta) {
((PotionMeta) im).setColor(color); potionMeta.setColor(color);
((PotionMeta) im).addCustomEffect(effect, true); potionMeta.addCustomEffect(effect, true);
if (effect.getType().equals(PotionEffectType.SATURATION)) { if (effect.getType().equals(PotionEffectType.SATURATION)) {
im.addItemFlags(ItemFlag.HIDE_POTION_EFFECTS); im.addItemFlags(ItemFlag.HIDE_POTION_EFFECTS);

View File

@ -40,14 +40,12 @@ public class MaterialTagSetting extends ItemSetting<List<String>> {
* *
* @return The default {@link Tag} * @return The default {@link Tag}
*/ */
@Nonnull public @Nonnull Tag<Material> getDefaultTag() {
public Tag<Material> getDefaultTag() {
return defaultTag; return defaultTag;
} }
@Nonnull
@Override @Override
protected String getErrorMessage() { protected @Nonnull String getErrorMessage() {
return "This List can only contain Materials in the format of e.g. REDSTONE_BLOCK"; return "This List can only contain Materials in the format of e.g. REDSTONE_BLOCK";
} }
@ -74,10 +72,10 @@ public class MaterialTagSetting extends ItemSetting<List<String>> {
* *
* @param tag * @param tag
* Our {@link Tag} * Our {@link Tag}
*
* @return The {@link String} {@link List} * @return The {@link String} {@link List}
*/ */
@Nonnull private static @Nonnull List<String> getAsStringList(@Nonnull Tag<Material> tag) {
private static List<String> getAsStringList(@Nonnull Tag<Material> tag) {
return tag.getValues().stream().map(Material::name).collect(Collectors.toList()); return tag.getValues().stream().map(Material::name).collect(Collectors.toList());
} }

View File

@ -1,10 +1,13 @@
package io.github.thebusybiscuit.slimefun4.api.player; package io.github.thebusybiscuit.slimefun4.api.player;
import java.io.File; import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
@ -132,6 +135,20 @@ public class PlayerBackpack {
}); });
} }
/**
* This will close the {@link Inventory} of this backpack for every {@link Player}
* that has opened it.
*/
public void closeForAll() {
Slimefun.runSync(() -> {
Iterator<HumanEntity> iterator = new ArrayList<>(inventory.getViewers()).iterator();
while (iterator.hasNext()) {
iterator.next().closeInventory();
}
});
}
/** /**
* This will change the current size of this Backpack to the specified size. * This will change the current size of this Backpack to the specified size.
* *

View File

@ -487,9 +487,7 @@ public class PlayerProfile {
if (!armorPiece.isPresent()) { if (!armorPiece.isPresent()) {
setId = null; setId = null;
} else if (armorPiece.get() instanceof ProtectiveArmor) { } else if (armorPiece.get() instanceof ProtectiveArmor protectedArmor) {
ProtectiveArmor protectedArmor = (ProtectiveArmor) armorPiece.get();
if (setId == null && protectedArmor.isFullSetRequired()) { if (setId == null && protectedArmor.isFullSetRequired()) {
setId = protectedArmor.getArmorSetId(); setId = protectedArmor.getArmorSetId();
} }
@ -517,7 +515,7 @@ public class PlayerProfile {
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
return obj instanceof PlayerProfile && uuid.equals(((PlayerProfile) obj).uuid); return obj instanceof PlayerProfile profile && uuid.equals(profile.uuid);
} }
@Override @Override

View File

@ -56,6 +56,7 @@ public class RecipeType implements Keyed {
public static final RecipeType MOB_DROP = new RecipeType(new NamespacedKey(Slimefun.instance(), "mob_drop"), new CustomItemStack(Material.IRON_SWORD, "&bMob Drop"), RecipeType::registerMobDrop, "", "&rKill the specified Mob to obtain this Item"); public static final RecipeType MOB_DROP = new RecipeType(new NamespacedKey(Slimefun.instance(), "mob_drop"), new CustomItemStack(Material.IRON_SWORD, "&bMob Drop"), RecipeType::registerMobDrop, "", "&rKill the specified Mob to obtain this Item");
public static final RecipeType BARTER_DROP = new RecipeType(new NamespacedKey(Slimefun.instance(), "barter_drop"), new CustomItemStack(Material.GOLD_INGOT, "&bBarter Drop"), RecipeType::registerBarterDrop, "&aBarter with piglins for a chance", "&ato obtain this item"); public static final RecipeType BARTER_DROP = new RecipeType(new NamespacedKey(Slimefun.instance(), "barter_drop"), new CustomItemStack(Material.GOLD_INGOT, "&bBarter Drop"), RecipeType::registerBarterDrop, "&aBarter with piglins for a chance", "&ato obtain this item");
public static final RecipeType INTERACT = new RecipeType(new NamespacedKey(Slimefun.instance(), "interact"), new CustomItemStack(Material.PLAYER_HEAD, "&bInteract", "", "&a&oRight click with this item"));
public static final RecipeType HEATED_PRESSURE_CHAMBER = new RecipeType(new NamespacedKey(Slimefun.instance(), "heated_pressure_chamber"), SlimefunItems.HEATED_PRESSURE_CHAMBER); public static final RecipeType HEATED_PRESSURE_CHAMBER = new RecipeType(new NamespacedKey(Slimefun.instance(), "heated_pressure_chamber"), SlimefunItems.HEATED_PRESSURE_CHAMBER);
public static final RecipeType FOOD_FABRICATOR = new RecipeType(new NamespacedKey(Slimefun.instance(), "food_fabricator"), SlimefunItems.FOOD_FABRICATOR); public static final RecipeType FOOD_FABRICATOR = new RecipeType(new NamespacedKey(Slimefun.instance(), "food_fabricator"), SlimefunItems.FOOD_FABRICATOR);
@ -99,8 +100,8 @@ public class RecipeType implements Keyed {
this.key = key; this.key = key;
this.consumer = callback; this.consumer = callback;
if (item instanceof SlimefunItemStack) { if (item instanceof SlimefunItemStack slimefunItemStack) {
this.machine = ((SlimefunItemStack) item).getItemId(); this.machine = slimefunItemStack.getItemId();
} else { } else {
this.machine = ""; this.machine = "";
} }
@ -109,7 +110,7 @@ public class RecipeType implements Keyed {
public RecipeType(NamespacedKey key, ItemStack item) { public RecipeType(NamespacedKey key, ItemStack item) {
this.key = key; this.key = key;
this.item = item; this.item = item;
this.machine = item instanceof SlimefunItemStack ? ((SlimefunItemStack) item).getItemId() : ""; this.machine = item instanceof SlimefunItemStack slimefunItemStack ? slimefunItemStack.getItemId() : "";
} }
public RecipeType(MinecraftRecipe<?> recipe) { public RecipeType(MinecraftRecipe<?> recipe) {
@ -124,8 +125,8 @@ public class RecipeType implements Keyed {
} else { } else {
SlimefunItem slimefunItem = SlimefunItem.getById(this.machine); SlimefunItem slimefunItem = SlimefunItem.getById(this.machine);
if (slimefunItem instanceof MultiBlockMachine) { if (slimefunItem instanceof MultiBlockMachine mbm) {
((MultiBlockMachine) slimefunItem).addRecipe(recipe, result); mbm.addRecipe(recipe, result);
} }
} }
} }
@ -149,8 +150,8 @@ public class RecipeType implements Keyed {
@Override @Override
public final boolean equals(Object obj) { public final boolean equals(Object obj) {
if (obj instanceof RecipeType) { if (obj instanceof RecipeType recipeType) {
return ((RecipeType) obj).getKey().equals(this.getKey()); return recipeType.getKey().equals(this.getKey());
} else { } else {
return false; return false;
} }

View File

@ -80,10 +80,9 @@ public abstract class SubCommand {
* *
* @return A possibly localized description of this {@link SubCommand} * @return A possibly localized description of this {@link SubCommand}
*/ */
@Nonnull public @Nonnull String getDescription(@Nonnull CommandSender sender) {
public String getDescription(@Nonnull CommandSender sender) { if (sender instanceof Player player) {
if (sender instanceof Player) { return Slimefun.getLocalization().getMessage(player, getDescription());
return Slimefun.getLocalization().getMessage((Player) sender, getDescription());
} else { } else {
return Slimefun.getLocalization().getMessage(getDescription()); return Slimefun.getLocalization().getMessage(getDescription());
} }

View File

@ -40,7 +40,7 @@ class BackpackCommand extends SubCommand {
@Override @Override
public void onExecute(CommandSender sender, String[] args) { public void onExecute(CommandSender sender, String[] args) {
if (sender instanceof Player) { if (sender instanceof Player player) {
if (sender.hasPermission("slimefun.command.backpack")) { if (sender.hasPermission("slimefun.command.backpack")) {
if (args.length != 3) { if (args.length != 3) {
Slimefun.getLocalization().sendMessage(sender, "messages.usage", true, msg -> msg.replace("%usage%", "/sf backpack <Player> <ID>")); Slimefun.getLocalization().sendMessage(sender, "messages.usage", true, msg -> msg.replace("%usage%", "/sf backpack <Player> <ID>"));
@ -71,7 +71,7 @@ class BackpackCommand extends SubCommand {
Slimefun.runSync(() -> { Slimefun.runSync(() -> {
ItemStack item = SlimefunItems.RESTORED_BACKPACK.clone(); ItemStack item = SlimefunItems.RESTORED_BACKPACK.clone();
Slimefun.getBackpackListener().setBackpackId(backpackOwner, item, 2, id); Slimefun.getBackpackListener().setBackpackId(backpackOwner, item, 2, id);
((Player) sender).getInventory().addItem(item); player.getInventory().addItem(item);
Slimefun.getLocalization().sendMessage(sender, "commands.backpack.restored-backpack-given"); Slimefun.getLocalization().sendMessage(sender, "commands.backpack.restored-backpack-given");
}); });
}); });

View File

@ -33,14 +33,12 @@ class ChargeCommand extends SubCommand {
@Override @Override
public void onExecute(CommandSender sender, String[] args) { public void onExecute(CommandSender sender, String[] args) {
if (sender instanceof Player) { if (sender instanceof Player player) {
if (sender.hasPermission("slimefun.command.charge")) { if (sender.hasPermission("slimefun.command.charge")) {
Player p = (Player) sender; ItemStack item = player.getInventory().getItemInMainHand();
ItemStack item = p.getInventory().getItemInMainHand();
SlimefunItem slimefunItem = SlimefunItem.getByItem(item); SlimefunItem slimefunItem = SlimefunItem.getByItem(item);
if (slimefunItem instanceof Rechargeable) { if (slimefunItem instanceof Rechargeable rechargeableItem) {
Rechargeable rechargeableItem = (Rechargeable) slimefunItem;
rechargeableItem.setItemCharge(item, rechargeableItem.getMaxItemCharge(item)); rechargeableItem.setItemCharge(item, rechargeableItem.getMaxItemCharge(item));
Slimefun.getLocalization().sendMessage(sender, "commands.charge.charge-success", true); Slimefun.getLocalization().sendMessage(sender, "commands.charge.charge-success", true);
} else { } else {

View File

@ -19,9 +19,9 @@ class CheatCommand extends SubCommand {
@Override @Override
public void onExecute(CommandSender sender, String[] args) { public void onExecute(CommandSender sender, String[] args) {
if (sender instanceof Player) { if (sender instanceof Player player) {
if (sender.hasPermission("slimefun.cheat.items")) { if (sender.hasPermission("slimefun.cheat.items")) {
SlimefunGuide.openCheatMenu((Player) sender); SlimefunGuide.openCheatMenu(player);
} else { } else {
Slimefun.getLocalization().sendMessage(sender, "messages.no-permission", true); Slimefun.getLocalization().sendMessage(sender, "messages.no-permission", true);
} }

View File

@ -19,8 +19,8 @@ class DebugFishCommand extends SubCommand {
@Override @Override
public void onExecute(CommandSender sender, String[] args) { public void onExecute(CommandSender sender, String[] args) {
if (sender instanceof Player && sender.hasPermission("slimefun.debugging")) { if (sender instanceof Player player && sender.hasPermission("slimefun.debugging")) {
((Player) sender).getInventory().addItem(SlimefunItems.DEBUG_FISH.clone()); player.getInventory().addItem(SlimefunItems.DEBUG_FISH.clone());
} else { } else {
Slimefun.getLocalization().sendMessage(sender, "messages.no-permission", true); Slimefun.getLocalization().sendMessage(sender, "messages.no-permission", true);
} }

View File

@ -20,10 +20,10 @@ class GuideCommand extends SubCommand {
@Override @Override
public void onExecute(CommandSender sender, String[] args) { public void onExecute(CommandSender sender, String[] args) {
if (sender instanceof Player) { if (sender instanceof Player player) {
if (sender.hasPermission("slimefun.command.guide")) { if (sender.hasPermission("slimefun.command.guide")) {
SlimefunGuideMode design = SlimefunGuide.getDefaultMode(); SlimefunGuideMode design = SlimefunGuide.getDefaultMode();
((Player) sender).getInventory().addItem(SlimefunGuide.getItem(design).clone()); player.getInventory().addItem(SlimefunGuide.getItem(design).clone());
} else { } else {
Slimefun.getLocalization().sendMessage(sender, "messages.no-permission", true); Slimefun.getLocalization().sendMessage(sender, "messages.no-permission", true);
} }

View File

@ -21,9 +21,9 @@ class OpenGuideCommand extends SubCommand {
@Override @Override
@ParametersAreNonnullByDefault @ParametersAreNonnullByDefault
public void onExecute(CommandSender sender, String[] args) { public void onExecute(CommandSender sender, String[] args) {
if (sender instanceof Player) { if (sender instanceof Player player) {
if (sender.hasPermission("slimefun.command.open_guide")) { if (sender.hasPermission("slimefun.command.open_guide")) {
SlimefunGuide.openGuide((Player) sender, SlimefunGuideMode.SURVIVAL_MODE); SlimefunGuide.openGuide(player, SlimefunGuideMode.SURVIVAL_MODE);
} else { } else {
Slimefun.getLocalization().sendMessage(sender, "messages.no-permission", true); Slimefun.getLocalization().sendMessage(sender, "messages.no-permission", true);
} }

View File

@ -33,6 +33,12 @@ class ResearchCommand extends SubCommand {
@Override @Override
public void onExecute(CommandSender sender, String[] args) { public void onExecute(CommandSender sender, String[] args) {
// Check if researching is even enabled
if (!Slimefun.getRegistry().isResearchingEnabled()) {
Slimefun.getLocalization().sendMessage(sender, "messages.researching-is-disabled");
return;
}
if (args.length == 3) { if (args.length == 3) {
if (!(sender instanceof Player) || sender.hasPermission("slimefun.cheat.researches")) { if (!(sender instanceof Player) || sender.hasPermission("slimefun.cheat.researches")) {
Optional<Player> player = PlayerList.findByName(args[1]); Optional<Player> player = PlayerList.findByName(args[1]);

View File

@ -23,11 +23,11 @@ class SearchCommand extends SubCommand {
@Override @Override
public void onExecute(CommandSender sender, String[] args) { public void onExecute(CommandSender sender, String[] args) {
if (sender instanceof Player) { if (sender instanceof Player player) {
if (sender.hasPermission("slimefun.command.search")) { if (sender.hasPermission("slimefun.command.search")) {
if (args.length > 1) { if (args.length > 1) {
String query = String.join(" ", Arrays.copyOfRange(args, 1, args.length)); String query = String.join(" ", Arrays.copyOfRange(args, 1, args.length));
PlayerProfile.get((Player) sender, profile -> SlimefunGuide.openSearch(profile, query, SlimefunGuideMode.SURVIVAL_MODE, true)); PlayerProfile.get(player, profile -> SlimefunGuide.openSearch(profile, query, SlimefunGuideMode.SURVIVAL_MODE, true));
} else { } else {
Slimefun.getLocalization().sendMessage(sender, "messages.usage", true, msg -> msg.replace("%usage%", "/sf search <SearchTerm>")); Slimefun.getLocalization().sendMessage(sender, "messages.usage", true, msg -> msg.replace("%usage%", "/sf search <SearchTerm>"));
} }

View File

@ -23,6 +23,12 @@ class StatsCommand extends SubCommand {
@Override @Override
public void onExecute(CommandSender sender, String[] args) { public void onExecute(CommandSender sender, String[] args) {
// Check if researching is even enabled
if (!Slimefun.getRegistry().isResearchingEnabled()) {
Slimefun.getLocalization().sendMessage(sender, "messages.researching-is-disabled");
return;
}
if (args.length > 1) { if (args.length > 1) {
if (sender.hasPermission("slimefun.stats.others") || sender instanceof ConsoleCommandSender) { if (sender.hasPermission("slimefun.stats.others") || sender instanceof ConsoleCommandSender) {
Optional<Player> player = PlayerList.findByName(args[1]); Optional<Player> player = PlayerList.findByName(args[1]);
@ -35,8 +41,8 @@ class StatsCommand extends SubCommand {
} else { } else {
Slimefun.getLocalization().sendMessage(sender, "messages.no-permission", true); Slimefun.getLocalization().sendMessage(sender, "messages.no-permission", true);
} }
} else if (sender instanceof Player) { } else if (sender instanceof Player player) {
PlayerProfile.get((Player) sender, profile -> profile.sendStats(sender)); PlayerProfile.get(player, profile -> profile.sendStats(sender));
} else { } else {
Slimefun.getLocalization().sendMessage(sender, "messages.only-players", true); Slimefun.getLocalization().sendMessage(sender, "messages.only-players", true);
} }

View File

@ -21,18 +21,17 @@ class TeleporterCommand extends SubCommand {
@Override @Override
public void onExecute(CommandSender sender, String[] args) { public void onExecute(CommandSender sender, String[] args) {
if (sender instanceof Player) { if (sender instanceof Player player) {
if (sender.hasPermission("slimefun.command.teleporter")) { if (sender.hasPermission("slimefun.command.teleporter")) {
if (args.length == 1) { if (args.length == 1) {
Player p = (Player) sender; Slimefun.getGPSNetwork().getTeleportationManager().openTeleporterGUI(player, player.getUniqueId(), player.getLocation().getBlock().getRelative(BlockFace.DOWN), 999999999);
Slimefun.getGPSNetwork().getTeleportationManager().openTeleporterGUI(p, p.getUniqueId(), p.getLocation().getBlock().getRelative(BlockFace.DOWN), 999999999);
} else if (args.length == 2) { } else if (args.length == 2) {
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
OfflinePlayer player = Bukkit.getOfflinePlayer(args[1]); OfflinePlayer targetPlayer = Bukkit.getOfflinePlayer(args[1]);
if (player.getName() != null) { if (targetPlayer.getName() != null) {
Slimefun.getGPSNetwork().getTeleportationManager().openTeleporterGUI((Player) sender, player.getUniqueId(), ((Player) sender).getLocation().getBlock().getRelative(BlockFace.DOWN), 999999999); Slimefun.getGPSNetwork().getTeleportationManager().openTeleporterGUI(player, targetPlayer.getUniqueId(), player.getLocation().getBlock().getRelative(BlockFace.DOWN), 999999999);
} else { } else {
Slimefun.getLocalization().sendMessage(sender, "messages.unknown-player", msg -> msg.replace("%player%", args[1])); Slimefun.getLocalization().sendMessage(sender, "messages.unknown-player", msg -> msg.replace("%player%", args[1]));
} }

View File

@ -88,8 +88,8 @@ class TimingsCommand extends SubCommand {
@Nonnull @Nonnull
private PerformanceInspector inspectorOf(@Nonnull CommandSender sender, boolean verbose) { private PerformanceInspector inspectorOf(@Nonnull CommandSender sender, boolean verbose) {
if (sender instanceof Player) { if (sender instanceof Player player) {
return new PlayerPerformanceInspector((Player) sender); return new PlayerPerformanceInspector(player);
} else { } else {
return new ConsolePerformanceInspector(sender, verbose); return new ConsolePerformanceInspector(sender, verbose);
} }

View File

@ -146,7 +146,7 @@ class VersionsCommand extends SubCommand {
secondaryColor = ChatColor.DARK_GREEN; secondaryColor = ChatColor.DARK_GREEN;
String authors = String.join(", ", plugin.getDescription().getAuthors()); String authors = String.join(", ", plugin.getDescription().getAuthors());
if (plugin instanceof SlimefunAddon && ((SlimefunAddon) plugin).getBugTrackerURL() != null) { if (plugin instanceof SlimefunAddon addon && addon.getBugTrackerURL() != null) {
// @formatter:off // @formatter:off
hoverEvent = new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text(new ComponentBuilder() hoverEvent = new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text(new ComponentBuilder()
.append("Author(s): ") .append("Author(s): ")
@ -158,7 +158,7 @@ class VersionsCommand extends SubCommand {
)); ));
// @formatter:on // @formatter:on
clickEvent = new ClickEvent(ClickEvent.Action.OPEN_URL, ((SlimefunAddon) plugin).getBugTrackerURL()); clickEvent = new ClickEvent(ClickEvent.Action.OPEN_URL, addon.getBugTrackerURL());
} else { } else {
// @formatter:off // @formatter:off
hoverEvent = new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text(new ComponentBuilder() hoverEvent = new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text(new ComponentBuilder()
@ -173,7 +173,7 @@ class VersionsCommand extends SubCommand {
primaryColor = ChatColor.RED; primaryColor = ChatColor.RED;
secondaryColor = ChatColor.DARK_RED; secondaryColor = ChatColor.DARK_RED;
if (plugin instanceof SlimefunAddon && ((SlimefunAddon) plugin).getBugTrackerURL() != null) { if (plugin instanceof SlimefunAddon addon && addon.getBugTrackerURL() != null) {
// @formatter:off // @formatter:off
hoverEvent = new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text(new ComponentBuilder() hoverEvent = new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text(new ComponentBuilder()
.append("This plugin is disabled.\nCheck the console for an error message.") .append("This plugin is disabled.\nCheck the console for an error message.")
@ -184,8 +184,6 @@ class VersionsCommand extends SubCommand {
)); ));
// @formatter:on // @formatter:on
SlimefunAddon addon = (SlimefunAddon) plugin;
if (addon.getBugTrackerURL() != null) { if (addon.getBugTrackerURL() != null) {
clickEvent = new ClickEvent(ClickEvent.Action.OPEN_URL, addon.getBugTrackerURL()); clickEvent = new ClickEvent(ClickEvent.Action.OPEN_URL, addon.getBugTrackerURL());
} }

View File

@ -188,14 +188,14 @@ public class GuideHistory {
private <T> void open(@Nonnull SlimefunGuideImplementation guide, @Nullable GuideEntry<T> entry) { private <T> void open(@Nonnull SlimefunGuideImplementation guide, @Nullable GuideEntry<T> entry) {
if (entry == null) { if (entry == null) {
guide.openMainMenu(profile, mainMenuPage); guide.openMainMenu(profile, mainMenuPage);
} else if (entry.getIndexedObject() instanceof ItemGroup) { } else if (entry.getIndexedObject() instanceof ItemGroup group) {
guide.openItemGroup(profile, (ItemGroup) entry.getIndexedObject(), entry.getPage()); guide.openItemGroup(profile, group, entry.getPage());
} else if (entry.getIndexedObject() instanceof SlimefunItem) { } else if (entry.getIndexedObject() instanceof SlimefunItem item) {
guide.displayItem(profile, (SlimefunItem) entry.getIndexedObject(), false); guide.displayItem(profile, item, false);
} else if (entry.getIndexedObject() instanceof ItemStack) { } else if (entry.getIndexedObject() instanceof ItemStack stack) {
guide.displayItem(profile, (ItemStack) entry.getIndexedObject(), entry.getPage(), false); guide.displayItem(profile, stack, entry.getPage(), false);
} else if (entry.getIndexedObject() instanceof String) { } else if (entry.getIndexedObject() instanceof String query) {
guide.openSearch(profile, (String) entry.getIndexedObject(), false); guide.openSearch(profile, query, false);
} else { } else {
throw new IllegalStateException("Unknown GuideHistory entry: " + entry.getIndexedObject()); throw new IllegalStateException("Unknown GuideHistory entry: " + entry.getIndexedObject());
} }

View File

@ -10,6 +10,7 @@ import org.bukkit.inventory.ItemStack;
import io.github.bakedlibs.dough.data.persistent.PersistentDataAPI; import io.github.bakedlibs.dough.data.persistent.PersistentDataAPI;
import io.github.bakedlibs.dough.items.CustomItemStack; import io.github.bakedlibs.dough.items.CustomItemStack;
import io.github.thebusybiscuit.slimefun4.api.SlimefunAddon; import io.github.thebusybiscuit.slimefun4.api.SlimefunAddon;
import io.github.thebusybiscuit.slimefun4.core.SlimefunRegistry;
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
class FireworksOption implements SlimefunGuideOption<Boolean> { class FireworksOption implements SlimefunGuideOption<Boolean> {
@ -26,7 +27,9 @@ class FireworksOption implements SlimefunGuideOption<Boolean> {
@Override @Override
public Optional<ItemStack> getDisplayItem(Player p, ItemStack guide) { public Optional<ItemStack> getDisplayItem(Player p, ItemStack guide) {
if (Slimefun.getRegistry().isResearchFireworkEnabled()) { SlimefunRegistry registry = Slimefun.getRegistry();
if (registry.isResearchingEnabled() && registry.isResearchFireworkEnabled()) {
boolean enabled = getSelectedOption(p, guide).orElse(true); boolean enabled = getSelectedOption(p, guide).orElse(true);
ItemStack item = new CustomItemStack(Material.FIREWORK_ROCKET, "&bFireworks: &" + (enabled ? "aYes" : "4No"), "", "&7You can now toggle whether you", "&7will be presented with a big firework", "&7upon researching an item.", "", "&7\u21E8 &eClick to " + (enabled ? "disable" : "enable") + " your fireworks"); ItemStack item = new CustomItemStack(Material.FIREWORK_ROCKET, "&bFireworks: &" + (enabled ? "aYes" : "4No"), "", "&7You can now toggle whether you", "&7will be presented with a big firework", "&7upon researching an item.", "", "&7\u21E8 &eClick to " + (enabled ? "disable" : "enable") + " your fireworks");
return Optional.of(item); return Optional.of(item);

View File

@ -13,6 +13,7 @@ import org.bukkit.inventory.ItemStack;
import io.github.bakedlibs.dough.data.persistent.PersistentDataAPI; import io.github.bakedlibs.dough.data.persistent.PersistentDataAPI;
import io.github.bakedlibs.dough.items.CustomItemStack; import io.github.bakedlibs.dough.items.CustomItemStack;
import io.github.thebusybiscuit.slimefun4.api.SlimefunAddon; import io.github.thebusybiscuit.slimefun4.api.SlimefunAddon;
import io.github.thebusybiscuit.slimefun4.core.SlimefunRegistry;
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
/** /**
@ -39,7 +40,9 @@ class LearningAnimationOption implements SlimefunGuideOption<Boolean> {
@Nonnull @Nonnull
@Override @Override
public Optional<ItemStack> getDisplayItem(@Nonnull Player p, @Nonnull ItemStack guide) { public Optional<ItemStack> getDisplayItem(@Nonnull Player p, @Nonnull ItemStack guide) {
if (Slimefun.getRegistry().isLearningAnimationDisabled()) { SlimefunRegistry registry = Slimefun.getRegistry();
if (!registry.isResearchingEnabled() || registry.isLearningAnimationDisabled()) {
return Optional.empty(); return Optional.empty();
} else { } else {
boolean enabled = getSelectedOption(p, guide).orElse(true); boolean enabled = getSelectedOption(p, guide).orElse(true);

View File

@ -76,10 +76,10 @@ public class RainbowTickHandler extends BlockTicker {
} }
for (Material type : materials) { for (Material type : materials) {
/** /*
* This BlockData is purely virtual and only created on startup, it should have This BlockData is purely virtual and only created on startup, it should have
* no impact on performance, in fact it should save performance as it preloads no impact on performance, in fact it should save performance as it preloads
* the data but also saves heavy calls for other Materials the data but also saves heavy calls for other Materials
*/ */
if (type.createBlockData() instanceof GlassPane) { if (type.createBlockData() instanceof GlassPane) {
return true; return true;
@ -92,9 +92,9 @@ public class RainbowTickHandler extends BlockTicker {
@Override @Override
public void tick(Block b, SlimefunItem item, Config data) { public void tick(Block b, SlimefunItem item, Config data) {
if (b.getType() == Material.AIR) { if (b.getType() == Material.AIR) {
/** /*
* The block was broken, setting the Material now would result in a The block was broken, setting the Material now would result in a
* duplication glitch duplication glitch
*/ */
return; return;
} }
@ -102,12 +102,9 @@ public class RainbowTickHandler extends BlockTicker {
if (glassPanes) { if (glassPanes) {
BlockData blockData = b.getBlockData(); BlockData blockData = b.getBlockData();
if (blockData instanceof GlassPane) { if (blockData instanceof GlassPane previousData) {
BlockData block = material.createBlockData(bd -> { BlockData block = material.createBlockData(bd -> {
if (bd instanceof GlassPane) { if (bd instanceof GlassPane nextData) {
GlassPane previousData = (GlassPane) blockData;
GlassPane nextData = (GlassPane) bd;
nextData.setWaterlogged(previousData.isWaterlogged()); nextData.setWaterlogged(previousData.isWaterlogged());
for (BlockFace face : previousData.getAllowedFaces()) { for (BlockFace face : previousData.getAllowedFaces()) {

View File

@ -155,7 +155,6 @@ public class MultiBlock {
public boolean isSymmetric() { public boolean isSymmetric() {
return isSymmetric; return isSymmetric;
} }
@Override @Override
public String toString() { public String toString() {
return "MultiBlock (" + item.getId() + ") {" + Arrays.toString(blocks) + "}"; return "MultiBlock (" + item.getId() + ") {" + Arrays.toString(blocks) + "}";

View File

@ -94,21 +94,14 @@ public class CargoNet extends AbstractItemNetwork implements HologramOwner {
return null; return null;
} }
switch (id) { return switch (id) {
case "CARGO_MANAGER": case "CARGO_MANAGER" -> NetworkComponent.REGULATOR;
return NetworkComponent.REGULATOR; case "CARGO_NODE" -> NetworkComponent.CONNECTOR;
case "CARGO_NODE": case "CARGO_NODE_INPUT",
return NetworkComponent.CONNECTOR; "CARGO_NODE_OUTPUT",
case "CARGO_NODE_INPUT": "CARGO_NODE_OUTPUT_ADVANCED" -> NetworkComponent.TERMINUS;
case "CARGO_NODE_OUTPUT": default -> null;
case "CARGO_NODE_OUTPUT_ADVANCED": };
case "CT_IMPORT_BUS":
case "CT_EXPORT_BUS":
case "CHEST_TERMINAL":
return NetworkComponent.TERMINUS;
default:
return null;
}
} }
@Override @Override
@ -123,15 +116,10 @@ public class CargoNet extends AbstractItemNetwork implements HologramOwner {
if (to == NetworkComponent.TERMINUS) { if (to == NetworkComponent.TERMINUS) {
String id = BlockStorage.checkID(l); String id = BlockStorage.checkID(l);
switch (id) { switch (id) {
case "CARGO_NODE_INPUT": case "CARGO_NODE_INPUT" -> inputNodes.add(l);
inputNodes.add(l); case "CARGO_NODE_OUTPUT",
break; "CARGO_NODE_OUTPUT_ADVANCED" -> outputNodes.add(l);
case "CARGO_NODE_OUTPUT": default -> {}
case "CARGO_NODE_OUTPUT_ADVANCED":
outputNodes.add(l);
break;
default:
break;
} }
} }
} }

View File

@ -151,15 +151,19 @@ class CargoNetworkTask implements Runnable {
boolean roundrobin = Objects.equals(cfg.getString("round-robin"), "true"); boolean roundrobin = Objects.equals(cfg.getString("round-robin"), "true");
boolean smartFill = Objects.equals(cfg.getString("smart-fill"), "true"); boolean smartFill = Objects.equals(cfg.getString("smart-fill"), "true");
int index = 0;
Collection<Location> destinations; Collection<Location> destinations;
if (roundrobin) { if (roundrobin) {
// The current round-robin index of the (unsorted) outputNodes list,
// or the index at which to start searching for valid output nodes
index = network.roundRobin.getOrDefault(inputNode, 0);
// Use an ArrayDeque to perform round-robin sorting // Use an ArrayDeque to perform round-robin sorting
// Since the impl for roundRobinSort just does Deque.addLast(Deque#removeFirst) // Since the impl for roundRobinSort just does Deque.addLast(Deque#removeFirst)
// An ArrayDequeue is preferable as opposed to a LinkedList: // An ArrayDequeue is preferable as opposed to a LinkedList:
// - The number of elements does not change. // - The number of elements does not change.
// - ArrayDequeue has better iterative performance // - ArrayDequeue has better iterative performance
Deque<Location> tempDestinations = new ArrayDeque<>(outputNodes); Deque<Location> tempDestinations = new ArrayDeque<>(outputNodes);
roundRobinSort(inputNode, tempDestinations); roundRobinSort(index, tempDestinations);
destinations = tempDestinations; destinations = tempDestinations;
} else { } else {
// Using an ArrayList here since we won't need to sort the destinations // Using an ArrayList here since we won't need to sort the destinations
@ -175,9 +179,14 @@ class CargoNetworkTask implements Runnable {
item = CargoUtils.insert(network, inventories, output.getBlock(), target.get(), smartFill, item, wrapper); item = CargoUtils.insert(network, inventories, output.getBlock(), target.get(), smartFill, item, wrapper);
if (item == null) { if (item == null) {
if (roundrobin) {
// The output was valid, set the round robin index to the node after this one
network.roundRobin.put(inputNode, (index + 1) % outputNodes.size());
}
break; break;
} }
} }
index++;
} }
return item; return item;
@ -187,27 +196,19 @@ class CargoNetworkTask implements Runnable {
* This method sorts a given {@link Deque} of output node locations using a semi-accurate * This method sorts a given {@link Deque} of output node locations using a semi-accurate
* round-robin method. * round-robin method.
* *
* @param inputNode * @param index
* The {@link Location} of the input node * The round-robin index of the input node
* @param outputNodes * @param outputNodes
* A {@link Deque} of {@link Location Locations} of the output nodes * A {@link Deque} of {@link Location Locations} of the output nodes
*/ */
private void roundRobinSort(Location inputNode, Deque<Location> outputNodes) { private void roundRobinSort(int index, Deque<Location> outputNodes) {
int index = network.roundRobin.getOrDefault(inputNode, 0);
if (index < outputNodes.size()) { if (index < outputNodes.size()) {
// Not ideal but actually not bad performance-wise over more elegant alternatives // Not ideal but actually not bad performance-wise over more elegant alternatives
for (int i = 0; i < index; i++) { for (int i = 0; i < index; i++) {
Location temp = outputNodes.removeFirst(); Location temp = outputNodes.removeFirst();
outputNodes.add(temp); outputNodes.add(temp);
} }
index++;
} else {
index = 1;
} }
network.roundRobin.put(inputNode, index);
} }
} }

View File

@ -70,21 +70,20 @@ final class CargoUtils {
Material type = block.getType(); Material type = block.getType();
switch (type) { // TODO: Add designated SlimefunTag
case CHEST: return switch (type) {
case TRAPPED_CHEST: case CHEST,
case FURNACE: TRAPPED_CHEST,
case DISPENSER: FURNACE,
case DROPPER: DISPENSER,
case HOPPER: DROPPER,
case BREWING_STAND: HOPPER,
case BARREL: BREWING_STAND,
case BLAST_FURNACE: BARREL,
case SMOKER: BLAST_FURNACE,
return true; SMOKER -> true;
default: default -> SlimefunTag.SHULKER_BOXES.isTagged(type);
return SlimefunTag.SHULKER_BOXES.isTagged(type); };
}
} }
@Nonnull @Nonnull
@ -145,8 +144,8 @@ final class CargoUtils {
BlockState state = PaperLib.getBlockState(target, false).getState(); BlockState state = PaperLib.getBlockState(target, false).getState();
if (state instanceof InventoryHolder) { if (state instanceof InventoryHolder inventoryHolder) {
inventory = ((InventoryHolder) state).getInventory(); inventory = inventoryHolder.getInventory();
inventories.put(target.getLocation(), inventory); inventories.put(target.getLocation(), inventory);
return withdrawFromVanillaInventory(network, node, template, inventory); return withdrawFromVanillaInventory(network, node, template, inventory);
} }
@ -230,8 +229,8 @@ final class CargoUtils {
BlockState state = PaperLib.getBlockState(target, false).getState(); BlockState state = PaperLib.getBlockState(target, false).getState();
if (state instanceof InventoryHolder) { if (state instanceof InventoryHolder inventoryHolder) {
inventory = ((InventoryHolder) state).getInventory(); inventory = inventoryHolder.getInventory();
inventories.put(target.getLocation(), inventory); inventories.put(target.getLocation(), inventory);
return withdrawFromVanillaInventory(network, node, inventory); return withdrawFromVanillaInventory(network, node, inventory);
} }
@ -278,8 +277,8 @@ final class CargoUtils {
BlockState state = PaperLib.getBlockState(target, false).getState(); BlockState state = PaperLib.getBlockState(target, false).getState();
if (state instanceof InventoryHolder) { if (state instanceof InventoryHolder inventoryHolder) {
inventory = ((InventoryHolder) state).getInventory(); inventory = inventoryHolder.getInventory();
inventories.put(target.getLocation(), inventory); inventories.put(target.getLocation(), inventory);
return insertIntoVanillaInventory(stack, wrapper, smartFill, inventory); return insertIntoVanillaInventory(stack, wrapper, smartFill, inventory);
} }

View File

@ -75,16 +75,13 @@ public class EnergyNet extends Network implements HologramOwner {
if (component == null) { if (component == null) {
return null; return null;
} else { } else {
switch (component.getEnergyComponentType()) { return switch (component.getEnergyComponentType()) {
case CONNECTOR: case CONNECTOR,
case CAPACITOR: CAPACITOR -> NetworkComponent.CONNECTOR;
return NetworkComponent.CONNECTOR; case CONSUMER,
case CONSUMER: GENERATOR -> NetworkComponent.TERMINUS;
case GENERATOR: default -> null;
return NetworkComponent.TERMINUS; };
default:
return null;
}
} }
} }
@ -106,10 +103,10 @@ public class EnergyNet extends Network implements HologramOwner {
consumers.put(l, component); consumers.put(l, component);
break; break;
case GENERATOR: case GENERATOR:
if (component instanceof EnergyNetProvider) { if (component instanceof EnergyNetProvider provider) {
generators.put(l, (EnergyNetProvider) component); generators.put(l, provider);
} else if (component instanceof SlimefunItem) { } else if (component instanceof SlimefunItem item) {
((SlimefunItem) component).warn("This Item is marked as a GENERATOR but does not implement the interface EnergyNetProvider!"); item.warn("This Item is marked as a GENERATOR but does not implement the interface EnergyNetProvider!");
} }
break; break;
default: default:
@ -275,8 +272,8 @@ public class EnergyNet extends Network implements HologramOwner {
private static EnergyNetComponent getComponent(@Nonnull Location l) { private static EnergyNetComponent getComponent(@Nonnull Location l) {
SlimefunItem item = BlockStorage.check(l); SlimefunItem item = BlockStorage.check(l);
if (item instanceof EnergyNetComponent) { if (item instanceof EnergyNetComponent component) {
return ((EnergyNetComponent) item); return component;
} }
return null; return null;

View File

@ -72,9 +72,9 @@ public class BlockDataService implements Keyed {
*/ */
BlockState state = b.getState(); BlockState state = b.getState();
if (state instanceof TileState) { if (state instanceof TileState tileState) {
try { try {
PersistentDataContainer container = ((TileState) state).getPersistentDataContainer(); PersistentDataContainer container = tileState.getPersistentDataContainer();
container.set(namespacedKey, PersistentDataType.STRING, value); container.set(namespacedKey, PersistentDataType.STRING, value);
state.update(); state.update();
} catch (Exception x) { } catch (Exception x) {
@ -111,8 +111,8 @@ public class BlockDataService implements Keyed {
@Nullable @Nullable
private PersistentDataContainer getPersistentDataContainer(@Nonnull BlockState state) { private PersistentDataContainer getPersistentDataContainer(@Nonnull BlockState state) {
if (state instanceof TileState) { if (state instanceof TileState tileState) {
return ((TileState) state).getPersistentDataContainer(); return tileState.getPersistentDataContainer();
} else { } else {
return null; return null;
} }
@ -137,31 +137,32 @@ public class BlockDataService implements Keyed {
return false; return false;
} }
switch (type) { // TODO: Add designated SlimefunTag
case PLAYER_HEAD: return switch (type) {
case PLAYER_WALL_HEAD: case PLAYER_HEAD,
case CHEST: PLAYER_WALL_HEAD,
case DISPENSER: CHEST,
case BREWING_STAND: DISPENSER,
case DROPPER: BREWING_STAND,
case FURNACE: DROPPER,
case BLAST_FURNACE: FURNACE,
case HOPPER: BLAST_FURNACE,
case LECTERN: HOPPER,
case JUKEBOX: LECTERN,
case ENDER_CHEST: JUKEBOX,
case ENCHANTING_TABLE: ENDER_CHEST,
case DAYLIGHT_DETECTOR: ENCHANTING_TABLE,
case SMOKER: DAYLIGHT_DETECTOR,
case BARREL: SMOKER,
case SPAWNER: BARREL,
case BEACON: SPAWNER,
BEACON ->
// All of the above Materials are Tile Entities // All of the above Materials are Tile Entities
return true; true;
default: default ->
// Otherwise we assume they're not Tile Entities // Otherwise we assume they're not Tile Entities
return false; false;
} };
} }
} }

View File

@ -99,8 +99,7 @@ public class MinecraftRecipeService {
* *
* @return An {@link Optional} describing the furnace output of the given {@link ItemStack} * @return An {@link Optional} describing the furnace output of the given {@link ItemStack}
*/ */
@Nonnull public @Nonnull Optional<ItemStack> getFurnaceOutput(@Nullable ItemStack input) {
public Optional<ItemStack> getFurnaceOutput(@Nullable ItemStack input) {
if (snapshot == null || input == null) { if (snapshot == null || input == null) {
return Optional.empty(); return Optional.empty();
} }
@ -132,18 +131,17 @@ public class MinecraftRecipeService {
* *
* @return An Array of {@link RecipeChoice} representing the shape of this {@link Recipe} * @return An Array of {@link RecipeChoice} representing the shape of this {@link Recipe}
*/ */
@Nonnull public @Nonnull RecipeChoice[] getRecipeShape(@Nonnull Recipe recipe) {
public RecipeChoice[] getRecipeShape(@Nonnull Recipe recipe) {
Validate.notNull(recipe, "Recipe must not be null!"); Validate.notNull(recipe, "Recipe must not be null!");
if (recipe instanceof ShapedRecipe) { if (recipe instanceof ShapedRecipe shapedRecipe) {
List<RecipeChoice> choices = new LinkedList<>(); List<RecipeChoice> choices = new LinkedList<>();
for (String row : ((ShapedRecipe) recipe).getShape()) { for (String row : shapedRecipe.getShape()) {
int columns = row.toCharArray().length; int columns = row.toCharArray().length;
for (char key : row.toCharArray()) { for (char key : row.toCharArray()) {
choices.add(((ShapedRecipe) recipe).getChoiceMap().get(key)); choices.add(shapedRecipe.getChoiceMap().get(key));
} }
while (columns < 3) { while (columns < 3) {
@ -167,8 +165,7 @@ public class MinecraftRecipeService {
* *
* @return An array of {@link Recipe Recipes} to craft the given {@link ItemStack} * @return An array of {@link Recipe Recipes} to craft the given {@link ItemStack}
*/ */
@Nonnull public @Nonnull Recipe[] getRecipesFor(@Nullable ItemStack item) {
public Recipe[] getRecipesFor(@Nullable ItemStack item) {
if (snapshot == null || item == null) { if (snapshot == null || item == null) {
return new Recipe[0]; return new Recipe[0];
} else { } else {
@ -187,8 +184,7 @@ public class MinecraftRecipeService {
* *
* @return The corresponding {@link Recipe} or null * @return The corresponding {@link Recipe} or null
*/ */
@Nullable public @Nullable Recipe getRecipe(@Nonnull NamespacedKey key) {
public Recipe getRecipe(@Nonnull NamespacedKey key) {
Validate.notNull(key, "The NamespacedKey should not be null"); Validate.notNull(key, "The NamespacedKey should not be null");
if (snapshot != null) { if (snapshot != null) {

View File

@ -82,7 +82,7 @@ class GitHubTask implements Runnable {
} }
for (GitHubConnector connector : gitHubService.getConnectors()) { for (GitHubConnector connector : gitHubService.getConnectors()) {
if (connector instanceof ContributionsConnector && !((ContributionsConnector) connector).hasFinished()) { if (connector instanceof ContributionsConnector contributionsConnector && !contributionsConnector.hasFinished()) {
return; return;
} }
} }

View File

@ -62,9 +62,9 @@ class Hologram {
ArmorStand getArmorStand() { ArmorStand getArmorStand() {
Entity n = Bukkit.getEntity(uniqueId); Entity n = Bukkit.getEntity(uniqueId);
if (n instanceof ArmorStand && n.isValid()) { if (n instanceof ArmorStand armorStand && n.isValid()) {
this.lastAccess = System.currentTimeMillis(); this.lastAccess = System.currentTimeMillis();
return (ArmorStand) n; return armorStand;
} else { } else {
this.lastAccess = 0; this.lastAccess = 0;
return null; return null;

View File

@ -191,11 +191,9 @@ public class HologramsService {
* @return Whether this could be a hologram * @return Whether this could be a hologram
*/ */
private boolean isHologram(@Nonnull Entity n) { private boolean isHologram(@Nonnull Entity n) {
if (n instanceof ArmorStand) { if (n instanceof ArmorStand armorStand) {
ArmorStand armorstand = (ArmorStand) n;
// The absolute minimum requirements to count as a hologram // The absolute minimum requirements to count as a hologram
return !armorstand.isVisible() && armorstand.isSilent() && !armorstand.hasGravity(); return !armorStand.isVisible() && armorStand.isSilent() && !armorStand.hasGravity();
} else { } else {
return false; return false;
} }
@ -216,22 +214,20 @@ public class HologramsService {
*/ */
@Nullable @Nullable
private Hologram getAsHologram(@Nonnull BlockPosition position, @Nonnull Entity entity, @Nonnull PersistentDataContainer container) { private Hologram getAsHologram(@Nonnull BlockPosition position, @Nonnull Entity entity, @Nonnull PersistentDataContainer container) {
if (entity instanceof ArmorStand) { if (entity instanceof ArmorStand armorStand) {
ArmorStand armorstand = (ArmorStand) entity; armorStand.setVisible(false);
armorStand.setInvulnerable(true);
armorstand.setVisible(false); armorStand.setSilent(true);
armorstand.setInvulnerable(true); armorStand.setMarker(true);
armorstand.setSilent(true); armorStand.setAI(false);
armorstand.setMarker(true); armorStand.setGravity(false);
armorstand.setAI(false); armorStand.setRemoveWhenFarAway(false);
armorstand.setGravity(false);
armorstand.setRemoveWhenFarAway(false);
// Set a persistent tag to re-identify the correct hologram later // Set a persistent tag to re-identify the correct hologram later
container.set(persistentDataKey, PersistentDataType.LONG, position.getPosition()); container.set(persistentDataKey, PersistentDataType.LONG, position.getPosition());
// Store in cache for faster access // Store in cache for faster access
Hologram hologram = new Hologram(armorstand.getUniqueId()); Hologram hologram = new Hologram(armorStand.getUniqueId());
cache.put(position, hologram); cache.put(position, hologram);
return hologram; return hologram;

View File

@ -50,13 +50,15 @@ public enum LanguagePreset {
HEBREW("he", TextDirection.RIGHT_TO_LEFT, "1ba086a2cc7272cf5ba49c80248546c22e5ef1bab54120e8a8e5d9e75b6a"), HEBREW("he", TextDirection.RIGHT_TO_LEFT, "1ba086a2cc7272cf5ba49c80248546c22e5ef1bab54120e8a8e5d9e75b6a"),
ARABIC("ar", TextDirection.RIGHT_TO_LEFT, "a4be759a9cf7f0a19a7e8e62f23789ad1d21cebae38af9d9541676a3db001572"), ARABIC("ar", TextDirection.RIGHT_TO_LEFT, "a4be759a9cf7f0a19a7e8e62f23789ad1d21cebae38af9d9541676a3db001572"),
TURKISH("tr", "9852b9aba3482348514c1034d0affe73545c9de679ae4647f99562b5e5f47d09"), TURKISH("tr", "9852b9aba3482348514c1034d0affe73545c9de679ae4647f99562b5e5f47d09"),
PERSIAN("fa", false, "5cd9badf1972583b663b44b1e027255de8f275aa1e89defcf77782ba6fcc652"), PERSIAN("fa", false, TextDirection.RIGHT_TO_LEFT, "5cd9badf1972583b663b44b1e027255de8f275aa1e89defcf77782ba6fcc652"),
SERBIAN("sr", false, "5b0483a4f0ddf4fbbc977b127b3d294d7a869f995366e3f50f6b05a70f522510"), SERBIAN("sr", false, "5b0483a4f0ddf4fbbc977b127b3d294d7a869f995366e3f50f6b05a70f522510"),
AFRIKAANS("af", false, "961a1eacc10524d1f45f23b0e487bb2fc33948d9676b418b19a3da0b109d0e3c"), AFRIKAANS("af", false, "961a1eacc10524d1f45f23b0e487bb2fc33948d9676b418b19a3da0b109d0e3c"),
MALAY("ms", false, "754b9041dea6db6db44750f1385a743adf653767b4b8802cad4c585dd3f5be46"), MALAY("ms", false, "754b9041dea6db6db44750f1385a743adf653767b4b8802cad4c585dd3f5be46"),
THAI("th", "2a7916e4a852f7e6f3f3de19c7fb57686a37bce834bd54684a7dbef8d53fb"), THAI("th", "2a7916e4a852f7e6f3f3de19c7fb57686a37bce834bd54684a7dbef8d53fb"),
MACEDONIAN("mk", "a0e0b0b5d87a855466980a101a757bcdb5f77d9f7287889f3efa998ee0472fc0"), MACEDONIAN("mk", "a0e0b0b5d87a855466980a101a757bcdb5f77d9f7287889f3efa998ee0472fc0"),
TAGALOG("tl", "9306c0c1ce6a9c61bb42a572c49e6d0ed20e0e6b3d122cc64c339cbf78e9e937"); TAGALOG("tl", "9306c0c1ce6a9c61bb42a572c49e6d0ed20e0e6b3d122cc64c339cbf78e9e937"),
SINHALA("si-LK", false, "4b26572c48344ee1fc4b2d89fd0866989a3e256ce19ee05384bc3ca76f2409c5"),
LITHUANIAN("lt", false, "de3d829741976d8330d6947d6eea64ee57aed2f26286ff63844e9089367c11");
private final String id; private final String id;
private final boolean releaseReady; private final boolean releaseReady;

View File

@ -348,8 +348,8 @@ public abstract class SlimefunLocalization implements Keyed {
String prefix = addPrefix ? getChatPrefix() : ""; String prefix = addPrefix ? getChatPrefix() : "";
if (recipient instanceof Player) { if (recipient instanceof Player player) {
recipient.sendMessage(ChatColors.color(prefix + getMessage((Player) recipient, key))); recipient.sendMessage(ChatColors.color(prefix + getMessage(player, key)));
} else { } else {
recipient.sendMessage(ChatColor.stripColor(ChatColors.color(prefix + getMessage(key)))); recipient.sendMessage(ChatColor.stripColor(ChatColors.color(prefix + getMessage(key))));
} }
@ -383,8 +383,8 @@ public abstract class SlimefunLocalization implements Keyed {
String prefix = addPrefix ? getChatPrefix() : ""; String prefix = addPrefix ? getChatPrefix() : "";
if (recipient instanceof Player) { if (recipient instanceof Player player) {
recipient.sendMessage(ChatColors.color(prefix + function.apply(getMessage((Player) recipient, key)))); recipient.sendMessage(ChatColors.color(prefix + function.apply(getMessage(player, key))));
} else { } else {
recipient.sendMessage(ChatColor.stripColor(ChatColors.color(prefix + function.apply(getMessage(key))))); recipient.sendMessage(ChatColor.stripColor(ChatColors.color(prefix + function.apply(getMessage(key)))));
} }
@ -393,8 +393,8 @@ public abstract class SlimefunLocalization implements Keyed {
public void sendMessages(@Nonnull CommandSender recipient, @Nonnull String key) { public void sendMessages(@Nonnull CommandSender recipient, @Nonnull String key) {
String prefix = getChatPrefix(); String prefix = getChatPrefix();
if (recipient instanceof Player) { if (recipient instanceof Player player) {
for (String translation : getMessages((Player) recipient, key)) { for (String translation : getMessages(player, key)) {
String message = ChatColors.color(prefix + translation); String message = ChatColors.color(prefix + translation);
recipient.sendMessage(message); recipient.sendMessage(message);
} }
@ -410,8 +410,8 @@ public abstract class SlimefunLocalization implements Keyed {
public void sendMessages(CommandSender recipient, String key, boolean addPrefix, UnaryOperator<String> function) { public void sendMessages(CommandSender recipient, String key, boolean addPrefix, UnaryOperator<String> function) {
String prefix = addPrefix ? getChatPrefix() : ""; String prefix = addPrefix ? getChatPrefix() : "";
if (recipient instanceof Player) { if (recipient instanceof Player player) {
for (String translation : getMessages((Player) recipient, key)) { for (String translation : getMessages(player, key)) {
String message = ChatColors.color(prefix + function.apply(translation)); String message = ChatColors.color(prefix + function.apply(translation));
recipient.sendMessage(message); recipient.sendMessage(message);
} }

View File

@ -95,9 +95,9 @@ class PerformanceSummary {
List<Entry<String, Long>> results = stream.sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())).collect(Collectors.toList()); List<Entry<String, Long>> results = stream.sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())).collect(Collectors.toList());
String prefix = count + " " + name + (count != 1 ? 's' : ""); String prefix = count + " " + name + (count != 1 ? 's' : "");
if (inspector instanceof PlayerPerformanceInspector) { if (inspector instanceof PlayerPerformanceInspector playerPerformanceInspector) {
TextComponent component = summarizeAsTextComponent(count, prefix, results, formatter); TextComponent component = summarizeAsTextComponent(count, prefix, results, formatter);
((PlayerPerformanceInspector) inspector).sendMessage(component); playerPerformanceInspector.sendMessage(component);
} else { } else {
String text = summarizeAsString(inspector, count, prefix, results, formatter); String text = summarizeAsString(inspector, count, prefix, results, formatter);
inspector.sendMessage(text); inspector.sendMessage(text);

View File

@ -143,9 +143,8 @@ final class ProfiledBlock {
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if (obj instanceof ProfiledBlock) { if (obj instanceof ProfiledBlock profiledBlock) {
ProfiledBlock block = (ProfiledBlock) obj; return position == profiledBlock.position && Objects.equals(world, profiledBlock.world);
return position == block.position && Objects.equals(world, block.world);
} }
return false; return false;

View File

@ -134,6 +134,11 @@ import me.mrCookieSlime.Slimefun.api.inventory.UniversalBlockMenu;
*/ */
public final class Slimefun extends JavaPlugin implements SlimefunAddon { public final class Slimefun extends JavaPlugin implements SlimefunAddon {
/**
* This is the Java version we recommend server owners to use.
* This does not necessarily mean that it's the minimum version
* required to run Slimefun.
*/
private static final int RECOMMENDED_JAVA_VERSION = 17; private static final int RECOMMENDED_JAVA_VERSION = 17;
/** /**

View File

@ -149,6 +149,7 @@ public final class SlimefunItems {
public static final SlimefunItemStack CARROT_JUICE = new SlimefunItemStack("CARROT_JUICE", Color.ORANGE, new PotionEffect(PotionEffectType.SATURATION, 5, 0), "&6Carrot Juice", "", LoreBuilder.hunger(3)); public static final SlimefunItemStack CARROT_JUICE = new SlimefunItemStack("CARROT_JUICE", Color.ORANGE, new PotionEffect(PotionEffectType.SATURATION, 5, 0), "&6Carrot Juice", "", LoreBuilder.hunger(3));
public static final SlimefunItemStack PUMPKIN_JUICE = new SlimefunItemStack("PUMPKIN_JUICE", Color.ORANGE, new PotionEffect(PotionEffectType.SATURATION, 5, 0), "&6Pumpkin Juice", "", LoreBuilder.hunger(3)); public static final SlimefunItemStack PUMPKIN_JUICE = new SlimefunItemStack("PUMPKIN_JUICE", Color.ORANGE, new PotionEffect(PotionEffectType.SATURATION, 5, 0), "&6Pumpkin Juice", "", LoreBuilder.hunger(3));
public static final SlimefunItemStack SWEET_BERRY_JUICE = new SlimefunItemStack("SWEET_BERRY_JUICE", Color.RED, new PotionEffect(PotionEffectType.SATURATION, 5, 0), "&cSweet Berry Juice", "", LoreBuilder.hunger(3)); public static final SlimefunItemStack SWEET_BERRY_JUICE = new SlimefunItemStack("SWEET_BERRY_JUICE", Color.RED, new PotionEffect(PotionEffectType.SATURATION, 5, 0), "&cSweet Berry Juice", "", LoreBuilder.hunger(3));
public static final SlimefunItemStack GLOW_BERRY_JUICE = new SlimefunItemStack("GLOW_BERRY_JUICE", Color.ORANGE, new PotionEffect(PotionEffectType.SATURATION, 5, 0), "&6Glow Berry Juice", "", LoreBuilder.hunger(3));
public static final SlimefunItemStack GOLDEN_APPLE_JUICE = new SlimefunItemStack("GOLDEN_APPLE_JUICE", Color.YELLOW, new PotionEffect(PotionEffectType.ABSORPTION, 20 * 20, 0), "&bGolden Apple Juice"); public static final SlimefunItemStack GOLDEN_APPLE_JUICE = new SlimefunItemStack("GOLDEN_APPLE_JUICE", Color.YELLOW, new PotionEffect(PotionEffectType.ABSORPTION, 20 * 20, 0), "&bGolden Apple Juice");
public static final SlimefunItemStack BEEF_JERKY = new SlimefunItemStack("BEEF_JERKY", Material.COOKED_BEEF, "&6Beef Jerky", "", "&fExtra saturating!"); public static final SlimefunItemStack BEEF_JERKY = new SlimefunItemStack("BEEF_JERKY", Material.COOKED_BEEF, "&6Beef Jerky", "", "&fExtra saturating!");
@ -204,7 +205,6 @@ public final class SlimefunItems {
public static final SlimefunItemStack SMELTERS_PICKAXE = new SlimefunItemStack("SMELTERS_PICKAXE", Material.DIAMOND_PICKAXE, "&6Smelter's Pickaxe", "&c&lAuto-Smelting", "", "&9Works with Fortune"); public static final SlimefunItemStack SMELTERS_PICKAXE = new SlimefunItemStack("SMELTERS_PICKAXE", Material.DIAMOND_PICKAXE, "&6Smelter's Pickaxe", "&c&lAuto-Smelting", "", "&9Works with Fortune");
public static final SlimefunItemStack LUMBER_AXE = new SlimefunItemStack("LUMBER_AXE", Material.DIAMOND_AXE, "&6Lumber Axe", "&a&oCuts down the whole Tree..."); public static final SlimefunItemStack LUMBER_AXE = new SlimefunItemStack("LUMBER_AXE", Material.DIAMOND_AXE, "&6Lumber Axe", "&a&oCuts down the whole Tree...");
public static final SlimefunItemStack PICKAXE_OF_CONTAINMENT = new SlimefunItemStack("PICKAXE_OF_CONTAINMENT", Material.IRON_PICKAXE, "&cPickaxe of Containment", "", "&9Can pickup Spawners"); public static final SlimefunItemStack PICKAXE_OF_CONTAINMENT = new SlimefunItemStack("PICKAXE_OF_CONTAINMENT", Material.IRON_PICKAXE, "&cPickaxe of Containment", "", "&9Can pickup Spawners");
public static final SlimefunItemStack HERCULES_PICKAXE = new SlimefunItemStack("HERCULES_PICKAXE", Material.IRON_PICKAXE, "&9Hercules' Pickaxe", "", "&fSo powerful that it", "&fcrushes all mined Ores", "&finto Dust...");
public static final SlimefunItemStack EXPLOSIVE_PICKAXE = new SlimefunItemStack("EXPLOSIVE_PICKAXE", Material.DIAMOND_PICKAXE, "&eExplosive Pickaxe", "", "&fAllows you to mine a good bit", "&fof Blocks at once...", "", "&9Works with Fortune"); public static final SlimefunItemStack EXPLOSIVE_PICKAXE = new SlimefunItemStack("EXPLOSIVE_PICKAXE", Material.DIAMOND_PICKAXE, "&eExplosive Pickaxe", "", "&fAllows you to mine a good bit", "&fof Blocks at once...", "", "&9Works with Fortune");
public static final SlimefunItemStack EXPLOSIVE_SHOVEL = new SlimefunItemStack("EXPLOSIVE_SHOVEL", Material.DIAMOND_SHOVEL, "&eExplosive Shovel", "", "&fAllows you to mine a good bit", "&fof diggable Blocks at once..."); public static final SlimefunItemStack EXPLOSIVE_SHOVEL = new SlimefunItemStack("EXPLOSIVE_SHOVEL", Material.DIAMOND_SHOVEL, "&eExplosive Shovel", "", "&fAllows you to mine a good bit", "&fof diggable Blocks at once...");
public static final SlimefunItemStack PICKAXE_OF_THE_SEEKER = new SlimefunItemStack("PICKAXE_OF_THE_SEEKER", Material.DIAMOND_PICKAXE, "&aPickaxe of the Seeker", "&fWill always point you to the nearest Ore", "&fbut might get damaged when doing it", "", "&7&eRight Click&7 to be pointed to the nearest Ore"); public static final SlimefunItemStack PICKAXE_OF_THE_SEEKER = new SlimefunItemStack("PICKAXE_OF_THE_SEEKER", Material.DIAMOND_PICKAXE, "&aPickaxe of the Seeker", "&fWill always point you to the nearest Ore", "&fbut might get damaged when doing it", "", "&7&eRight Click&7 to be pointed to the nearest Ore");
@ -213,9 +213,6 @@ public final class SlimefunItems {
public static final SlimefunItemStack CLIMBING_PICK = new SlimefunItemStack("CLIMBING_PICK", Material.IRON_PICKAXE, "&bClimbing Pick", "", "&fAllows you to climb certain surfaces", "&fby right-clicking.", "&fEnchant this pick with Efficiency to", "&fclimb even faster!"); public static final SlimefunItemStack CLIMBING_PICK = new SlimefunItemStack("CLIMBING_PICK", Material.IRON_PICKAXE, "&bClimbing Pick", "", "&fAllows you to climb certain surfaces", "&fby right-clicking.", "&fEnchant this pick with Efficiency to", "&fclimb even faster!");
static { static {
HERCULES_PICKAXE.addUnsafeEnchantment(Enchantment.DURABILITY, 5);
HERCULES_PICKAXE.addUnsafeEnchantment(Enchantment.DIG_SPEED, 3);
COBALT_PICKAXE.addUnsafeEnchantment(Enchantment.DURABILITY, 10); COBALT_PICKAXE.addUnsafeEnchantment(Enchantment.DURABILITY, 10);
COBALT_PICKAXE.addUnsafeEnchantment(Enchantment.DIG_SPEED, 6); COBALT_PICKAXE.addUnsafeEnchantment(Enchantment.DIG_SPEED, 6);
} }
@ -835,6 +832,7 @@ public final class SlimefunItems {
public static final SlimefunItemStack FREEZER = new SlimefunItemStack("FREEZER", Material.LIGHT_BLUE_STAINED_GLASS, "&bFreezer", "", LoreBuilder.machine(MachineTier.ADVANCED, MachineType.MACHINE), LoreBuilder.speed(1), LoreBuilder.powerBuffer(256), LoreBuilder.powerPerSecond(18)); public static final SlimefunItemStack FREEZER = new SlimefunItemStack("FREEZER", Material.LIGHT_BLUE_STAINED_GLASS, "&bFreezer", "", LoreBuilder.machine(MachineTier.ADVANCED, MachineType.MACHINE), LoreBuilder.speed(1), LoreBuilder.powerBuffer(256), LoreBuilder.powerPerSecond(18));
public static final SlimefunItemStack FREEZER_2 = new SlimefunItemStack("FREEZER_2", Material.LIGHT_BLUE_STAINED_GLASS, "&bFreezer &7(&eII&7)", "", LoreBuilder.machine(MachineTier.END_GAME, MachineType.MACHINE), LoreBuilder.speed(2), LoreBuilder.powerBuffer(256), LoreBuilder.powerPerSecond(30)); public static final SlimefunItemStack FREEZER_2 = new SlimefunItemStack("FREEZER_2", Material.LIGHT_BLUE_STAINED_GLASS, "&bFreezer &7(&eII&7)", "", LoreBuilder.machine(MachineTier.END_GAME, MachineType.MACHINE), LoreBuilder.speed(2), LoreBuilder.powerBuffer(256), LoreBuilder.powerPerSecond(30));
public static final SlimefunItemStack FREEZER_3 = new SlimefunItemStack("FREEZER_3", Material.LIGHT_GRAY_STAINED_GLASS, "&bFreezer &7(&eIII&7)", "", LoreBuilder.machine(MachineTier.END_GAME, MachineType.MACHINE), LoreBuilder.speed(3), LoreBuilder.powerBuffer(256), LoreBuilder.powerPerSecond(42));
public static final SlimefunItemStack ELECTRIC_GOLD_PAN = new SlimefunItemStack("ELECTRIC_GOLD_PAN", Material.BROWN_TERRACOTTA, "&6Electric Gold Pan", "", LoreBuilder.machine(MachineTier.BASIC, MachineType.MACHINE), LoreBuilder.speed(1), LoreBuilder.powerPerSecond(2)); public static final SlimefunItemStack ELECTRIC_GOLD_PAN = new SlimefunItemStack("ELECTRIC_GOLD_PAN", Material.BROWN_TERRACOTTA, "&6Electric Gold Pan", "", LoreBuilder.machine(MachineTier.BASIC, MachineType.MACHINE), LoreBuilder.speed(1), LoreBuilder.powerPerSecond(2));
public static final SlimefunItemStack ELECTRIC_GOLD_PAN_2 = new SlimefunItemStack("ELECTRIC_GOLD_PAN_2", Material.BROWN_TERRACOTTA, "&6Electric Gold Pan &7(&eII&7)", "", LoreBuilder.machine(MachineTier.BASIC, MachineType.MACHINE), LoreBuilder.speed(3), LoreBuilder.powerPerSecond(4)); public static final SlimefunItemStack ELECTRIC_GOLD_PAN_2 = new SlimefunItemStack("ELECTRIC_GOLD_PAN_2", Material.BROWN_TERRACOTTA, "&6Electric Gold Pan &7(&eII&7)", "", LoreBuilder.machine(MachineTier.BASIC, MachineType.MACHINE), LoreBuilder.speed(3), LoreBuilder.powerPerSecond(4));

View File

@ -54,7 +54,7 @@ public class CheatSheetSlimefunGuide extends SurvivalSlimefunGuide {
List<ItemGroup> groups = new LinkedList<>(); List<ItemGroup> groups = new LinkedList<>();
for (ItemGroup group : Slimefun.getRegistry().getAllItemGroups()) { for (ItemGroup group : Slimefun.getRegistry().getAllItemGroups()) {
if (!(group instanceof FlexItemGroup) || ((FlexItemGroup) group).isVisible(p, profile, getMode())) { if (!(group instanceof FlexItemGroup flexItemGroup) || flexItemGroup.isVisible(p, profile, getMode())) {
groups.add(group); groups.add(group);
} }
} }

View File

@ -119,8 +119,8 @@ public class SurvivalSlimefunGuide implements SlimefunGuideImplementation {
for (ItemGroup group : Slimefun.getRegistry().getAllItemGroups()) { for (ItemGroup group : Slimefun.getRegistry().getAllItemGroups()) {
try { try {
if (group instanceof FlexItemGroup) { if (group instanceof FlexItemGroup flexItemGroup) {
if (((FlexItemGroup) group).isVisible(p, profile, getMode())) { if (flexItemGroup.isVisible(p, profile, getMode())) {
groups.add(group); groups.add(group);
} }
} else if (!group.isHidden(p)) { } else if (!group.isHidden(p)) {
@ -233,8 +233,8 @@ public class SurvivalSlimefunGuide implements SlimefunGuideImplementation {
return; return;
} }
if (itemGroup instanceof FlexItemGroup) { if (itemGroup instanceof FlexItemGroup flexItemGroup) {
((FlexItemGroup) itemGroup).open(p, profile, getMode()); flexItemGroup.open(p, profile, getMode());
return; return;
} }
@ -493,19 +493,19 @@ public class SurvivalSlimefunGuide implements SlimefunGuideImplementation {
private <T extends Recipe> void showRecipeChoices(T recipe, ItemStack[] recipeItems, AsyncRecipeChoiceTask task) { private <T extends Recipe> void showRecipeChoices(T recipe, ItemStack[] recipeItems, AsyncRecipeChoiceTask task) {
RecipeChoice[] choices = Slimefun.getMinecraftRecipeService().getRecipeShape(recipe); RecipeChoice[] choices = Slimefun.getMinecraftRecipeService().getRecipeShape(recipe);
if (choices.length == 1 && choices[0] instanceof MaterialChoice) { if (choices.length == 1 && choices[0] instanceof MaterialChoice materialChoice) {
recipeItems[4] = new ItemStack(((MaterialChoice) choices[0]).getChoices().get(0)); recipeItems[4] = new ItemStack(materialChoice.getChoices().get(0));
if (((MaterialChoice) choices[0]).getChoices().size() > 1) { if (materialChoice.getChoices().size() > 1) {
task.add(recipeSlots[4], (MaterialChoice) choices[0]); task.add(recipeSlots[4], materialChoice);
} }
} else { } else {
for (int i = 0; i < choices.length; i++) { for (int i = 0; i < choices.length; i++) {
if (choices[i] instanceof MaterialChoice) { if (choices[i] instanceof MaterialChoice materialChoice) {
recipeItems[i] = new ItemStack(((MaterialChoice) choices[i]).getChoices().get(0)); recipeItems[i] = new ItemStack(materialChoice.getChoices().get(0));
if (((MaterialChoice) choices[i]).getChoices().size() > 1) { if (materialChoice.getChoices().size() > 1) {
task.add(recipeSlots[i], (MaterialChoice) choices[i]); task.add(recipeSlots[i], materialChoice);
} }
} }
} }
@ -545,8 +545,8 @@ public class SurvivalSlimefunGuide implements SlimefunGuideImplementation {
displayItem(menu, profile, p, item, result, recipeType, recipe, task); displayItem(menu, profile, p, item, result, recipeType, recipe, task);
if (item instanceof RecipeDisplayItem) { if (item instanceof RecipeDisplayItem recipeDisplayItem) {
displayRecipes(p, profile, menu, (RecipeDisplayItem) item, 0); displayRecipes(p, profile, menu, recipeDisplayItem, 0);
} }
menu.open(p); menu.open(p);

View File

@ -78,8 +78,8 @@ public class VanillaInventoryDropHandler<T extends BlockState & InventoryHolder>
@Nonnull @Nonnull
protected Inventory getInventory(@Nonnull T inventoryHolder) { protected Inventory getInventory(@Nonnull T inventoryHolder) {
if (inventoryHolder instanceof Chest) { if (inventoryHolder instanceof Chest chest) {
return ((Chest) inventoryHolder).getBlockInventory(); return chest.getBlockInventory();
} else { } else {
return inventoryHolder.getInventory(); return inventoryHolder.getInventory();
} }

View File

@ -0,0 +1,27 @@
package io.github.thebusybiscuit.slimefun4.implementation.items;
import javax.annotation.ParametersAreNonnullByDefault;
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.attributes.NotConfigurable;
/**
* The {@link HiddenItem} is a {@link NotConfigurable} {@link SlimefunItem}
* that is hidden from the Slimefun guide.
*
* @author char321
*
*/
public class HiddenItem extends SlimefunItem implements NotConfigurable {
@ParametersAreNonnullByDefault
public HiddenItem(ItemGroup itemGroup, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(itemGroup, item, recipeType, recipe);
this.setHidden(true);
}
}

View File

@ -86,8 +86,8 @@ public class AncientPedestal extends SimpleSlimefunItem<BlockDispenseHandler> {
Location l = pedestal.getLocation().add(0.5, 1.2, 0.5); 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, this::testItem)) {
if (n instanceof Item) { if (n instanceof Item item) {
return Optional.of((Item) n); return Optional.of(item);
} }
} }
@ -95,8 +95,7 @@ public class AncientPedestal extends SimpleSlimefunItem<BlockDispenseHandler> {
} }
private boolean testItem(@Nullable Entity n) { private boolean testItem(@Nullable Entity n) {
if (n instanceof Item && n.isValid()) { if (n instanceof Item item && n.isValid()) {
Item item = (Item) n;
ItemMeta meta = item.getItemStack().getItemMeta(); ItemMeta meta = item.getItemStack().getItemMeta();
return meta.hasDisplayName() && meta.getDisplayName().startsWith(ITEM_PREFIX); return meta.hasDisplayName() && meta.getDisplayName().startsWith(ITEM_PREFIX);

View File

@ -2,6 +2,8 @@ package io.github.thebusybiscuit.slimefun4.implementation.items.androids;
import java.util.function.Predicate; import java.util.function.Predicate;
import javax.annotation.ParametersAreNonnullByDefault;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.block.BlockFace; import org.bukkit.block.BlockFace;
import org.bukkit.entity.ArmorStand; import org.bukkit.entity.ArmorStand;
@ -20,6 +22,7 @@ public class ButcherAndroid extends ProgrammableAndroid {
private static final String METADATA_KEY = "android_killer"; private static final String METADATA_KEY = "android_killer";
@ParametersAreNonnullByDefault
public ButcherAndroid(ItemGroup itemGroup, int tier, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { public ButcherAndroid(ItemGroup itemGroup, int tier, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(itemGroup, tier, item, recipeType, recipe); super(itemGroup, tier, item, recipeType, recipe);
} }
@ -34,27 +37,17 @@ public class ButcherAndroid extends ProgrammableAndroid {
double damage = getTier() >= 3 ? 20D : 4D * getTier(); double damage = getTier() >= 3 ? 20D : 4D * getTier();
double radius = 4.0 + getTier(); double radius = 4.0 + getTier();
for (Entity n : b.getWorld().getNearbyEntities(b.getLocation(), radius, radius, radius, n -> n instanceof LivingEntity && !(n instanceof ArmorStand) && !(n instanceof Player) && n.isValid() && predicate.test((LivingEntity) n))) { for (Entity n : b.getWorld().getNearbyEntities(b.getLocation(), radius, radius, radius, n -> n instanceof LivingEntity livingEntity && !(n instanceof ArmorStand) && !(n instanceof Player) && n.isValid() && predicate.test(livingEntity))) {
boolean attack = false; // Check if our android is facing this entity.
boolean willAttack = switch (face) {
case NORTH -> n.getLocation().getZ() < b.getZ();
case EAST -> n.getLocation().getX() > b.getX();
case SOUTH -> n.getLocation().getZ() > b.getZ();
case WEST -> n.getLocation().getX() < b.getX();
default -> false;
};
switch (face) { if (willAttack) {
case NORTH:
attack = n.getLocation().getZ() < b.getZ();
break;
case EAST:
attack = n.getLocation().getX() > b.getX();
break;
case SOUTH:
attack = n.getLocation().getZ() > b.getZ();
break;
case WEST:
attack = n.getLocation().getX() < b.getX();
break;
default:
break;
}
if (attack) {
if (n.hasMetadata(METADATA_KEY)) { if (n.hasMetadata(METADATA_KEY)) {
n.removeMetadata(METADATA_KEY, Slimefun.instance()); n.removeMetadata(METADATA_KEY, Slimefun.instance());
} }

View File

@ -42,7 +42,7 @@ public class FarmerAndroid extends ProgrammableAndroid {
return; return;
} }
if (data instanceof Ageable && ((Ageable) data).getAge() >= ((Ageable) data).getMaximumAge()) { if (data instanceof Ageable ageable && ageable.getAge() >= ageable.getMaximumAge()) {
drop = getDropFromCrop(blockType); drop = getDropFromCrop(blockType);
} }
@ -57,8 +57,8 @@ public class FarmerAndroid extends ProgrammableAndroid {
if (drop != null && menu.pushItem(drop, getOutputSlots()) == null) { if (drop != null && menu.pushItem(drop, getOutputSlots()) == null) {
block.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, blockType); block.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, blockType);
if (data instanceof Ageable) { if (data instanceof Ageable ageable) {
((Ageable) data).setAge(0); ageable.setAge(0);
block.setBlockData(data); block.setBlockData(data);
} }
} }
@ -68,24 +68,16 @@ public class FarmerAndroid extends ProgrammableAndroid {
private ItemStack getDropFromCrop(Material crop) { private ItemStack getDropFromCrop(Material crop) {
Random random = ThreadLocalRandom.current(); Random random = ThreadLocalRandom.current();
switch (crop) { return switch (crop) {
case WHEAT: case WHEAT -> new ItemStack(Material.WHEAT, random.nextInt(2) + 1);
return new ItemStack(Material.WHEAT, random.nextInt(2) + 1); case POTATOES -> new ItemStack(Material.POTATO, random.nextInt(3) + 1);
case POTATOES: case CARROTS -> new ItemStack(Material.CARROT, random.nextInt(3) + 1);
return new ItemStack(Material.POTATO, random.nextInt(3) + 1); case BEETROOTS -> new ItemStack(Material.BEETROOT, random.nextInt(3) + 1);
case CARROTS: case COCOA -> new ItemStack(Material.COCOA_BEANS, random.nextInt(3) + 1);
return new ItemStack(Material.CARROT, random.nextInt(3) + 1); case NETHER_WART -> new ItemStack(Material.NETHER_WART, random.nextInt(3) + 1);
case BEETROOTS: case SWEET_BERRY_BUSH -> new ItemStack(Material.SWEET_BERRIES, random.nextInt(3) + 1);
return new ItemStack(Material.BEETROOT, random.nextInt(3) + 1); default -> null;
case COCOA: };
return new ItemStack(Material.COCOA_BEANS, random.nextInt(3) + 1);
case NETHER_WART:
return new ItemStack(Material.NETHER_WART, random.nextInt(3) + 1);
case SWEET_BERRY_BUSH:
return new ItemStack(Material.SWEET_BERRIES, random.nextInt(3) + 1);
default:
return null;
}
} }
} }

View File

@ -156,8 +156,8 @@ public class ProgrammableAndroid extends SlimefunItem implements InventoryBlock,
BlockStorage.addBlockInfo(b, "paused", "true"); BlockStorage.addBlockInfo(b, "paused", "true");
BlockData blockData = Material.PLAYER_HEAD.createBlockData(data -> { BlockData blockData = Material.PLAYER_HEAD.createBlockData(data -> {
if (data instanceof Rotatable) { if (data instanceof Rotatable rotatable) {
((Rotatable) data).setRotation(p.getFacing()); rotatable.setRotation(p.getFacing());
} }
}); });
@ -207,16 +207,12 @@ public class ProgrammableAndroid extends SlimefunItem implements InventoryBlock,
* @return The required type of fuel * @return The required type of fuel
*/ */
public AndroidFuelSource getFuelSource() { public AndroidFuelSource getFuelSource() {
switch (getTier()) { return switch (getTier()) {
case 1: case 1 -> AndroidFuelSource.SOLID;
return AndroidFuelSource.SOLID; case 2 -> AndroidFuelSource.LIQUID;
case 2: case 3 -> AndroidFuelSource.NUCLEAR;
return AndroidFuelSource.LIQUID; default -> throw new IllegalStateException("Cannot convert the following Android tier to a fuel type: " + getTier());
case 3: };
return AndroidFuelSource.NUCLEAR;
default:
throw new IllegalStateException("Cannot convert the following Android tier to a fuel type: " + getTier());
}
} }
@Override @Override
@ -602,7 +598,7 @@ public class ProgrammableAndroid extends SlimefunItem implements InventoryBlock,
private void registerDefaultFuelTypes() { private void registerDefaultFuelTypes() {
switch (getFuelSource()) { switch (getFuelSource()) {
case SOLID: case SOLID -> {
registerFuelType(new MachineFuel(80, new ItemStack(Material.COAL_BLOCK))); registerFuelType(new MachineFuel(80, new ItemStack(Material.COAL_BLOCK)));
registerFuelType(new MachineFuel(45, new ItemStack(Material.BLAZE_ROD))); registerFuelType(new MachineFuel(45, new ItemStack(Material.BLAZE_ROD)));
registerFuelType(new MachineFuel(70, new ItemStack(Material.DRIED_KELP_BLOCK))); registerFuelType(new MachineFuel(70, new ItemStack(Material.DRIED_KELP_BLOCK)));
@ -620,20 +616,18 @@ public class ProgrammableAndroid extends SlimefunItem implements InventoryBlock,
for (Material mat : Tag.PLANKS.getValues()) { for (Material mat : Tag.PLANKS.getValues()) {
registerFuelType(new MachineFuel(1, new ItemStack(mat))); registerFuelType(new MachineFuel(1, new ItemStack(mat)));
} }
}
break; case LIQUID -> {
case LIQUID:
registerFuelType(new MachineFuel(100, new ItemStack(Material.LAVA_BUCKET))); registerFuelType(new MachineFuel(100, new ItemStack(Material.LAVA_BUCKET)));
registerFuelType(new MachineFuel(200, SlimefunItems.OIL_BUCKET)); registerFuelType(new MachineFuel(200, SlimefunItems.OIL_BUCKET));
registerFuelType(new MachineFuel(500, SlimefunItems.FUEL_BUCKET)); registerFuelType(new MachineFuel(500, SlimefunItems.FUEL_BUCKET));
break; }
case NUCLEAR: case NUCLEAR -> {
registerFuelType(new MachineFuel(2500, SlimefunItems.URANIUM)); registerFuelType(new MachineFuel(2500, SlimefunItems.URANIUM));
registerFuelType(new MachineFuel(1200, SlimefunItems.NEPTUNIUM)); registerFuelType(new MachineFuel(1200, SlimefunItems.NEPTUNIUM));
registerFuelType(new MachineFuel(3000, SlimefunItems.BOOSTED_URANIUM)); registerFuelType(new MachineFuel(3000, SlimefunItems.BOOSTED_URANIUM));
break; }
default: default -> throw new IllegalStateException("Unhandled Fuel Source: " + getFuelSource());
throw new IllegalStateException("Unhandled Fuel Source: " + getFuelSource());
} }
} }
@ -760,8 +754,7 @@ public class ProgrammableAndroid extends SlimefunItem implements InventoryBlock,
BlockFace rotation = POSSIBLE_ROTATIONS.get(index); BlockFace rotation = POSSIBLE_ROTATIONS.get(index);
BlockData blockData = Material.PLAYER_HEAD.createBlockData(data -> { BlockData blockData = Material.PLAYER_HEAD.createBlockData(data -> {
if (data instanceof Rotatable) { if (data instanceof Rotatable rotatable) {
Rotatable rotatable = ((Rotatable) data);
rotatable.setRotation(rotation.getOppositeFace()); rotatable.setRotation(rotation.getOppositeFace());
} }
}); });
@ -774,14 +767,12 @@ public class ProgrammableAndroid extends SlimefunItem implements InventoryBlock,
if (facedBlock.getType() == Material.DISPENSER && BlockStorage.check(facedBlock, "ANDROID_INTERFACE_ITEMS")) { if (facedBlock.getType() == Material.DISPENSER && BlockStorage.check(facedBlock, "ANDROID_INTERFACE_ITEMS")) {
BlockState state = PaperLib.getBlockState(facedBlock, false).getState(); BlockState state = PaperLib.getBlockState(facedBlock, false).getState();
if (state instanceof Dispenser) { if (state instanceof Dispenser dispenser) {
Dispenser d = (Dispenser) state;
for (int slot : getOutputSlots()) { for (int slot : getOutputSlots()) {
ItemStack stack = menu.getItemInSlot(slot); ItemStack stack = menu.getItemInSlot(slot);
if (stack != null) { if (stack != null) {
Optional<ItemStack> optional = d.getInventory().addItem(stack).values().stream().findFirst(); Optional<ItemStack> optional = dispenser.getInventory().addItem(stack).values().stream().findFirst();
if (optional.isPresent()) { if (optional.isPresent()) {
menu.replaceExistingItem(slot, optional.get()); menu.replaceExistingItem(slot, optional.get());
@ -798,14 +789,12 @@ public class ProgrammableAndroid extends SlimefunItem implements InventoryBlock,
if (facedBlock.getType() == Material.DISPENSER && BlockStorage.check(facedBlock, "ANDROID_INTERFACE_FUEL")) { if (facedBlock.getType() == Material.DISPENSER && BlockStorage.check(facedBlock, "ANDROID_INTERFACE_FUEL")) {
BlockState state = PaperLib.getBlockState(facedBlock, false).getState(); BlockState state = PaperLib.getBlockState(facedBlock, false).getState();
if (state instanceof Dispenser) { if (state instanceof Dispenser dispenser) {
Dispenser d = (Dispenser) state;
for (int slot = 0; slot < 9; slot++) { for (int slot = 0; slot < 9; slot++) {
ItemStack item = d.getInventory().getItem(slot); ItemStack item = dispenser.getInventory().getItem(slot);
if (item != null) { if (item != null) {
insertFuel(menu, d.getInventory(), slot, menu.getItemInSlot(43), item); insertFuel(menu, dispenser.getInventory(), slot, menu.getItemInSlot(43), item);
} }
} }
} }
@ -897,8 +886,7 @@ public class ProgrammableAndroid extends SlimefunItem implements InventoryBlock,
} }
BlockData blockData = Material.PLAYER_HEAD.createBlockData(data -> { BlockData blockData = Material.PLAYER_HEAD.createBlockData(data -> {
if (data instanceof Rotatable) { if (data instanceof Rotatable rotatable) {
Rotatable rotatable = ((Rotatable) data);
rotatable.setRotation(face.getOppositeFace()); rotatable.setRotation(face.getOppositeFace());
} }
}); });

View File

@ -159,6 +159,18 @@ public class WoodcutterAndroid extends ProgrammableAndroid {
} }
} }
if (Slimefun.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_19)) {
switch (logType) {
case MANGROVE_LOG:
case STRIPPED_MANGROVE_LOG:
saplingType = Material.MANGROVE_PROPAGULE;
soilRequirement = SlimefunTag.MANGROVE_BASE_BLOCKS::isTagged;
break;
default:
break;
}
}
if (saplingType != null && soilRequirement != null) { if (saplingType != null && soilRequirement != null) {
if (soilRequirement.test(block.getRelative(BlockFace.DOWN).getType())) { if (soilRequirement.test(block.getRelative(BlockFace.DOWN).getType())) {
// Replant the block // Replant the block

View File

@ -51,7 +51,7 @@ public class StomperBoots extends SlimefunItem {
player.setVelocity(new Vector(0, 0.7, 0)); player.setVelocity(new Vector(0, 0.7, 0));
for (Entity entity : player.getNearbyEntities(4, 4, 4)) { for (Entity entity : player.getNearbyEntities(4, 4, 4)) {
if (entity instanceof LivingEntity && canPush(player, (LivingEntity) entity)) { if (entity instanceof LivingEntity livingEntity && canPush(player, livingEntity)) {
Vector velocity = getShockwave(player.getLocation(), entity.getLocation()); Vector velocity = getShockwave(player.getLocation(), entity.getLocation());
entity.setVelocity(velocity); entity.setVelocity(velocity);
@ -61,7 +61,7 @@ public class StomperBoots extends SlimefunItem {
Bukkit.getPluginManager().callEvent(event); Bukkit.getPluginManager().callEvent(event);
if (!event.isCancelled()) { if (!event.isCancelled()) {
((LivingEntity) entity).damage(event.getDamage()); livingEntity.damage(event.getDamage());
} }
} }
} }

View File

@ -175,8 +175,8 @@ public abstract class AbstractAutoCrafter extends SlimefunItem implements Energy
if (isValidInventory(targetBlock)) { if (isValidInventory(targetBlock)) {
BlockState state = PaperLib.getBlockState(targetBlock, false).getState(); BlockState state = PaperLib.getBlockState(targetBlock, false).getState();
if (state instanceof InventoryHolder) { if (state instanceof InventoryHolder inventoryHolder) {
Inventory inv = ((InventoryHolder) state).getInventory(); Inventory inv = inventoryHolder.getInventory();
if (craft(inv, recipe)) { if (craft(inv, recipe)) {
// We are done crafting! // We are done crafting!
@ -202,14 +202,13 @@ public abstract class AbstractAutoCrafter extends SlimefunItem implements Energy
protected boolean isValidInventory(@Nonnull Block block) { protected boolean isValidInventory(@Nonnull Block block) {
Material type = block.getType(); Material type = block.getType();
switch (type) { // TODO: Add designated SlimefunTag
case CHEST: return switch (type) {
case TRAPPED_CHEST: case CHEST,
case BARREL: TRAPPED_CHEST,
return true; BARREL -> true;
default: default -> SlimefunTag.SHULKER_BOXES.isTagged(type);
return SlimefunTag.SHULKER_BOXES.isTagged(type); };
}
} }
/** /**
@ -251,16 +250,16 @@ public abstract class AbstractAutoCrafter extends SlimefunItem implements Energy
BlockStateSnapshotResult result = PaperLib.getBlockState(b, false); BlockStateSnapshotResult result = PaperLib.getBlockState(b, false);
BlockState state = result.getState(); BlockState state = result.getState();
if (state instanceof Skull) { if (state instanceof Skull skull) {
if (recipe == null) { if (recipe == null) {
// Clear the value from persistent data storage // Clear the value from persistent data storage
PersistentDataAPI.remove((Skull) state, recipeStorageKey); PersistentDataAPI.remove(skull, recipeStorageKey);
// Also remove the "enabled" state since this should be per-recipe. // Also remove the "enabled" state since this should be per-recipe.
PersistentDataAPI.remove((Skull) state, recipeEnabledKey); PersistentDataAPI.remove(skull, recipeEnabledKey);
} else { } else {
// Store the value to persistent data storage // Store the value to persistent data storage
PersistentDataAPI.setString((Skull) state, recipeStorageKey, recipe.toString()); PersistentDataAPI.setString(skull, recipeStorageKey, recipe.toString());
} }
// Fixes #2899 - Update the BlockState if necessary // Fixes #2899 - Update the BlockState if necessary
@ -337,12 +336,12 @@ public abstract class AbstractAutoCrafter extends SlimefunItem implements Energy
BlockState state = PaperLib.getBlockState(b, false).getState(); BlockState state = PaperLib.getBlockState(b, false).getState();
// Make sure the block is still a Skull // Make sure the block is still a Skull
if (state instanceof Skull) { if (state instanceof Skull skull) {
if (enabled) { if (enabled) {
PersistentDataAPI.remove((Skull) state, recipeEnabledKey); PersistentDataAPI.remove(skull, recipeEnabledKey);
Slimefun.getLocalization().sendMessage(p, "messages.auto-crafting.re-enabled"); Slimefun.getLocalization().sendMessage(p, "messages.auto-crafting.re-enabled");
} else { } else {
PersistentDataAPI.setByte((Skull) state, recipeEnabledKey, (byte) 1); PersistentDataAPI.setByte(skull, recipeEnabledKey, (byte) 1);
Slimefun.getLocalization().sendMessage(p, "messages.auto-crafting.temporarily-disabled"); Slimefun.getLocalization().sendMessage(p, "messages.auto-crafting.temporarily-disabled");
} }
} }

View File

@ -136,10 +136,10 @@ public abstract class AbstractRecipe {
*/ */
@Nullable @Nullable
public static AbstractRecipe of(@Nullable Recipe recipe) { public static AbstractRecipe of(@Nullable Recipe recipe) {
if (recipe instanceof ShapedRecipe) { if (recipe instanceof ShapedRecipe shapedRecipe) {
return new VanillaRecipe((ShapedRecipe) recipe); return new VanillaRecipe(shapedRecipe);
} else if (recipe instanceof ShapelessRecipe) { } else if (recipe instanceof ShapelessRecipe shapelessRecipe) {
return new VanillaRecipe((ShapelessRecipe) recipe); return new VanillaRecipe(shapelessRecipe);
} else { } else {
return null; return null;
} }

View File

@ -60,9 +60,9 @@ public class SlimefunAutoCrafter extends AbstractAutoCrafter {
BlockState state = PaperLib.getBlockState(b, false).getState(); BlockState state = PaperLib.getBlockState(b, false).getState();
if (state instanceof Skull) { if (state instanceof Skull skull) {
// Read the stored value from persistent data storage // Read the stored value from persistent data storage
PersistentDataContainer container = ((Skull) state).getPersistentDataContainer(); PersistentDataContainer container = skull.getPersistentDataContainer();
String value = container.get(recipeStorageKey, PersistentDataType.STRING); String value = container.get(recipeStorageKey, PersistentDataType.STRING);
SlimefunItem item = SlimefunItem.getById(value); SlimefunItem item = SlimefunItem.getById(value);

View File

@ -61,9 +61,9 @@ public class VanillaAutoCrafter extends AbstractAutoCrafter {
public @Nullable AbstractRecipe getSelectedRecipe(@Nonnull Block b) { public @Nullable AbstractRecipe getSelectedRecipe(@Nonnull Block b) {
BlockState state = PaperLib.getBlockState(b, false).getState(); BlockState state = PaperLib.getBlockState(b, false).getState();
if (state instanceof Skull) { if (state instanceof Skull skull) {
// Read the stored value from persistent data storage // Read the stored value from persistent data storage
PersistentDataContainer container = ((Skull) state).getPersistentDataContainer(); PersistentDataContainer container = skull.getPersistentDataContainer();
String value = container.get(recipeStorageKey, PersistentDataType.STRING); String value = container.get(recipeStorageKey, PersistentDataType.STRING);
if (value != null) { if (value != null) {

View File

@ -81,19 +81,19 @@ class VanillaRecipe extends AbstractRecipe {
RecipeChoice[] choices = Slimefun.getMinecraftRecipeService().getRecipeShape(recipe); RecipeChoice[] choices = Slimefun.getMinecraftRecipeService().getRecipeShape(recipe);
ItemStack[] items = new ItemStack[9]; ItemStack[] items = new ItemStack[9];
if (choices.length == 1 && choices[0] instanceof MaterialChoice) { if (choices.length == 1 && choices[0] instanceof MaterialChoice materialChoice) {
items[4] = new ItemStack(((MaterialChoice) choices[0]).getChoices().get(0)); items[4] = new ItemStack(materialChoice.getChoices().get(0));
if (((MaterialChoice) choices[0]).getChoices().size() > 1) { if (materialChoice.getChoices().size() > 1) {
task.add(slots[4], (MaterialChoice) choices[0]); task.add(slots[4], materialChoice);
} }
} else { } else {
for (int i = 0; i < choices.length; i++) { for (int i = 0; i < choices.length; i++) {
if (choices[i] instanceof MaterialChoice) { if (choices[i] instanceof MaterialChoice materialChoice) {
items[i] = new ItemStack(((MaterialChoice) choices[i]).getChoices().get(0)); items[i] = new ItemStack(materialChoice.getChoices().get(0));
if (((MaterialChoice) choices[i]).getChoices().size() > 1) { if (materialChoice.getChoices().size() > 1) {
task.add(slots[i], (MaterialChoice) choices[i]); task.add(slots[i], materialChoice);
} }
} }
} }
@ -107,8 +107,8 @@ class VanillaRecipe extends AbstractRecipe {
@Override @Override
public String toString() { public String toString() {
if (recipe instanceof Keyed) { if (recipe instanceof Keyed keyed) {
return ((Keyed) recipe).getKey().toString(); return keyed.getKey().toString();
} else { } else {
return "invalid-recipe"; return "invalid-recipe";
} }

View File

@ -83,12 +83,11 @@ public abstract class AbstractMonsterSpawner extends SlimefunItem {
ItemMeta meta = item.getItemMeta(); ItemMeta meta = item.getItemMeta();
// Fixes #2583 - Proper NBT handling of Spawners // Fixes #2583 - Proper NBT handling of Spawners
if (meta instanceof BlockStateMeta) { if (meta instanceof BlockStateMeta stateMeta) {
BlockStateMeta stateMeta = (BlockStateMeta) meta;
BlockState state = stateMeta.getBlockState(); BlockState state = stateMeta.getBlockState();
if (state instanceof CreatureSpawner) { if (state instanceof CreatureSpawner spawner) {
((CreatureSpawner) state).setSpawnedType(type); spawner.setSpawnedType(type);
} }
stateMeta.setBlockState(state); stateMeta.setBlockState(state);

View File

@ -222,8 +222,7 @@ public class BlockPlacer extends SlimefunItem {
if (meta.hasDisplayName()) { if (meta.hasDisplayName()) {
BlockStateSnapshotResult blockState = PaperLib.getBlockState(facedBlock, false); BlockStateSnapshotResult blockState = PaperLib.getBlockState(facedBlock, false);
if ((blockState.getState() instanceof Nameable)) { if (blockState.getState() instanceof Nameable nameable) {
Nameable nameable = ((Nameable) blockState.getState());
nameable.setCustomName(meta.getDisplayName()); nameable.setCustomName(meta.getDisplayName());
if (blockState.isSnapshot()) { if (blockState.isSnapshot()) {

View File

@ -203,10 +203,9 @@ public class Crucible extends SimpleSlimefunItem<BlockUseHandler> implements Rec
// Fixes #2903 - Cancel physics update to resolve weird overlapping // Fixes #2903 - Cancel physics update to resolve weird overlapping
block.setType(water ? Material.WATER : Material.LAVA, false); block.setType(water ? Material.WATER : Material.LAVA, false);
} else { } else {
if (water && block.getBlockData() instanceof Waterlogged) { if (water && block.getBlockData() instanceof Waterlogged waterlogged) {
Waterlogged wl = (Waterlogged) block.getBlockData(); waterlogged.setWaterlogged(true);
wl.setWaterlogged(true); block.setBlockData(waterlogged, false);
block.setBlockData(wl, false);
block.getWorld().playSound(block.getLocation(), Sound.ENTITY_PLAYER_SPLASH, 1F, 1F); block.getWorld().playSound(block.getLocation(), Sound.ENTITY_PLAYER_SPLASH, 1F, 1F);
return; return;
} }

View File

@ -87,8 +87,8 @@ public class EnhancedFurnace extends SimpleSlimefunItem<BlockTicker> {
BlockState state = result.getState(); BlockState state = result.getState();
// Check if the BlockState is a Furnace and cooking something // Check if the BlockState is a Furnace and cooking something
if (state instanceof Furnace && ((Furnace) state).getCookTime() > 0) { if (state instanceof Furnace furnace && furnace.getCookTime() > 0) {
setProgress((Furnace) state); setProgress(furnace);
// Only update if necessary // Only update if necessary
if (result.isSnapshot()) { if (result.isSnapshot()) {

View File

@ -140,11 +140,11 @@ public class HologramProjector extends SlimefunItem implements HologramOwner {
Location l = new Location(projector.getWorld(), projector.getX() + 0.5, projector.getY() + offset, projector.getZ() + 0.5); Location l = new Location(projector.getWorld(), projector.getX() + 0.5, projector.getY() + offset, projector.getZ() + 0.5);
for (Entity n : l.getChunk().getEntities()) { for (Entity n : l.getChunk().getEntities()) {
if (n instanceof ArmorStand && l.distanceSquared(n.getLocation()) < 0.4) { if (n instanceof ArmorStand armorStand && l.distanceSquared(n.getLocation()) < 0.4) {
String customName = n.getCustomName(); String customName = n.getCustomName();
if (customName != null && customName.equals(nametag)) { if (customName != null && customName.equals(nametag)) {
return (ArmorStand) n; return armorStand;
} }
} }
} }

View File

@ -116,8 +116,8 @@ public class IgnitionChamber extends SlimefunItem {
if (block.getType() == Material.DROPPER && BlockStorage.check(block) instanceof IgnitionChamber) { if (block.getType() == Material.DROPPER && BlockStorage.check(block) instanceof IgnitionChamber) {
BlockState state = PaperLib.getBlockState(b.getRelative(face), false).getState(); BlockState state = PaperLib.getBlockState(b.getRelative(face), false).getState();
if (state instanceof Dropper) { if (state instanceof Dropper dropper) {
return ((Dropper) state).getInventory(); return dropper.getInventory();
} }
} }
} }

View File

@ -83,8 +83,8 @@ public class OutputChest extends SlimefunItem {
// Found the output chest! Now, let's check if we can fit the product in it. // Found the output chest! Now, let's check if we can fit the product in it.
BlockState state = PaperLib.getBlockState(potentialOutput, false).getState(); BlockState state = PaperLib.getBlockState(potentialOutput, false).getState();
if (state instanceof Chest) { if (state instanceof Chest chest) {
Inventory inv = ((Chest) state).getInventory(); Inventory inv = chest.getInventory();
// Check if the Item fits into that inventory. // Check if the Item fits into that inventory.
if (InvUtils.fits(inv, item)) { if (InvUtils.fits(inv, item)) {

View File

@ -7,12 +7,12 @@ import org.bukkit.block.Block;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import io.github.bakedlibs.dough.common.ChatColors;
import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup; import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup;
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
import io.github.thebusybiscuit.slimefun4.core.handlers.BlockUseHandler; import io.github.thebusybiscuit.slimefun4.core.handlers.BlockUseHandler;
import io.github.thebusybiscuit.slimefun4.core.networks.cargo.CargoNet; import io.github.thebusybiscuit.slimefun4.core.networks.cargo.CargoNet;
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem; import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
/** /**
@ -32,9 +32,8 @@ public class CargoConnectorNode extends SimpleSlimefunItem<BlockUseHandler> {
super(itemGroup, item, recipeType, recipe, recipeOutput); super(itemGroup, item, recipeType, recipe, recipeOutput);
} }
@Nonnull
@Override @Override
public BlockUseHandler getItemHandler() { public @Nonnull BlockUseHandler getItemHandler() {
return e -> { return e -> {
if (!e.getClickedBlock().isPresent()) { if (!e.getClickedBlock().isPresent()) {
return; return;
@ -44,9 +43,9 @@ public class CargoConnectorNode extends SimpleSlimefunItem<BlockUseHandler> {
Block b = e.getClickedBlock().get(); Block b = e.getClickedBlock().get();
if (CargoNet.getNetworkFromLocation(b.getLocation()) != null) { if (CargoNet.getNetworkFromLocation(b.getLocation()) != null) {
p.sendMessage(ChatColors.color("&7Connected: " + "&2\u2714")); Slimefun.getLocalization().sendActionbarMessage(p, "machines.CARGO_NODES.connected", false);
} else { } else {
p.sendMessage(ChatColors.color("&7Connected: " + "&4\u2718")); Slimefun.getLocalization().sendActionbarMessage(p, "machines.CARGO_NODES.not-connected", false);
} }
}; };
} }

View File

@ -43,10 +43,7 @@ public class Multimeter extends SimpleSlimefunItem<ItemUseHandler> {
if (e.getClickedBlock().isPresent() && block.isPresent()) { if (e.getClickedBlock().isPresent() && block.isPresent()) {
SlimefunItem item = block.get(); SlimefunItem item = block.get();
if (item instanceof EnergyNetComponent) { if (item instanceof EnergyNetComponent component && component.isChargeable()) {
EnergyNetComponent component = (EnergyNetComponent) item;
if (component.isChargeable()) {
e.cancel(); e.cancel();
Location l = e.getClickedBlock().get().getLocation(); Location l = e.getClickedBlock().get().getLocation();
@ -59,7 +56,6 @@ public class Multimeter extends SimpleSlimefunItem<ItemUseHandler> {
p.sendMessage(""); p.sendMessage("");
} }
} }
}
}; };
} }
} }

View File

@ -67,8 +67,8 @@ public class SolarHelmet extends SlimefunItem {
private void recharge(@Nullable ItemStack item) { private void recharge(@Nullable ItemStack item) {
SlimefunItem sfItem = SlimefunItem.getByItem(item); SlimefunItem sfItem = SlimefunItem.getByItem(item);
if (sfItem instanceof Rechargeable) { if (sfItem instanceof Rechargeable rechargeable) {
((Rechargeable) sfItem).addItemCharge(item, charge.getValue().floatValue()); rechargeable.addItemCharge(item, charge.getValue().floatValue());
} }
} }

View File

@ -5,6 +5,8 @@ import java.util.List;
import javax.annotation.ParametersAreNonnullByDefault; import javax.annotation.ParametersAreNonnullByDefault;
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.Tag; import org.bukkit.Tag;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
@ -80,6 +82,11 @@ public class AutoDrier extends AContainer implements RecipeDisplayItem, NotHoppe
recipeList.add(new ItemStack(Material.COOKED_SALMON)); recipeList.add(new ItemStack(Material.COOKED_SALMON));
recipeList.add(SlimefunItems.FISH_JERKY); recipeList.add(SlimefunItems.FISH_JERKY);
if (Slimefun.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_19)) {
recipeList.add(new ItemStack(Material.MUD));
recipeList.add(new ItemStack(Material.CLAY));
}
for (Material sapling : Tag.SAPLINGS.getValues()) { for (Material sapling : Tag.SAPLINGS.getValues()) {
recipeList.add(new ItemStack(sapling)); recipeList.add(new ItemStack(sapling));
recipeList.add(new ItemStack(Material.STICK, 2)); recipeList.add(new ItemStack(Material.STICK, 2));

View File

@ -53,10 +53,10 @@ public class ChargingBench extends AContainer {
private boolean charge(Block b, BlockMenu inv, int slot, ItemStack item) { private boolean charge(Block b, BlockMenu inv, int slot, ItemStack item) {
SlimefunItem sfItem = SlimefunItem.getByItem(item); SlimefunItem sfItem = SlimefunItem.getByItem(item);
if (sfItem instanceof Rechargeable) { if (sfItem instanceof Rechargeable rechargeable) {
float charge = getEnergyConsumption() / 2F; float charge = getEnergyConsumption() / 2F;
if (((Rechargeable) sfItem).addItemCharge(item, charge)) { if (rechargeable.addItemCharge(item, charge)) {
removeCharge(b.getLocation(), getEnergyConsumption()); removeCharge(b.getLocation(), getEnergyConsumption());
} else if (inv.fits(item, getOutputSlots())) { } else if (inv.fits(item, getOutputSlots())) {
inv.pushItem(item, getOutputSlots()); inv.pushItem(item, getOutputSlots());

View File

@ -37,8 +37,8 @@ public class ElectricFurnace extends AContainer implements NotHopperable {
for (FurnaceRecipe recipe : snapshot.getRecipes(FurnaceRecipe.class)) { for (FurnaceRecipe recipe : snapshot.getRecipes(FurnaceRecipe.class)) {
RecipeChoice choice = recipe.getInputChoice(); RecipeChoice choice = recipe.getInputChoice();
if (choice instanceof MaterialChoice) { if (choice instanceof MaterialChoice materialChoice) {
for (Material input : ((MaterialChoice) choice).getChoices()) { for (Material input : materialChoice.getChoices()) {
registerRecipe(4, new ItemStack[] { new ItemStack(input) }, new ItemStack[] { recipe.getResult() }); registerRecipe(4, new ItemStack[] { new ItemStack(input) }, new ItemStack[] { recipe.getResult() });
} }
} }

View File

@ -10,6 +10,7 @@ import org.bukkit.Material;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup; 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.items.SlimefunItemStack;
import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
import io.github.thebusybiscuit.slimefun4.core.attributes.RecipeDisplayItem; import io.github.thebusybiscuit.slimefun4.core.attributes.RecipeDisplayItem;
@ -34,6 +35,8 @@ import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu;
*/ */
public class ElectricGoldPan extends AContainer implements RecipeDisplayItem { public class ElectricGoldPan extends AContainer implements RecipeDisplayItem {
private final ItemSetting<Boolean> overrideOutputLimit = new ItemSetting<>(this, "override-output-limit", false);
private final GoldPan goldPan = SlimefunItems.GOLD_PAN.getItem(GoldPan.class); private final GoldPan goldPan = SlimefunItems.GOLD_PAN.getItem(GoldPan.class);
private final GoldPan netherGoldPan = SlimefunItems.NETHER_GOLD_PAN.getItem(GoldPan.class); private final GoldPan netherGoldPan = SlimefunItems.NETHER_GOLD_PAN.getItem(GoldPan.class);
@ -43,6 +46,21 @@ public class ElectricGoldPan extends AContainer implements RecipeDisplayItem {
@ParametersAreNonnullByDefault @ParametersAreNonnullByDefault
public ElectricGoldPan(ItemGroup itemGroup, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { public ElectricGoldPan(ItemGroup itemGroup, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(itemGroup, item, recipeType, recipe); super(itemGroup, item, recipeType, recipe);
addItemSetting(overrideOutputLimit);
}
/**
* This returns whether the {@link ElectricGoldPan} will stop proccessing inputs
* if both output slots contain items or if that default behavior should be
* overriden 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
*/
public boolean isOutputLimitOverriden() {
return overrideOutputLimit.getValue();
} }
@Override @Override
@ -62,7 +80,7 @@ public class ElectricGoldPan extends AContainer implements RecipeDisplayItem {
@Override @Override
protected MachineRecipe findNextRecipe(BlockMenu menu) { protected MachineRecipe findNextRecipe(BlockMenu menu) {
if (!hasFreeSlot(menu)) { if (!isOutputLimitOverriden() && !hasFreeSlot(menu)) {
return null; return null;
} }

View File

@ -227,16 +227,14 @@ public class FluidPump extends SimpleSlimefunItem<BlockTicker> implements Invent
} }
private @Nonnull ItemStack getFilledBucket(@Nonnull Block fluid) { private @Nonnull ItemStack getFilledBucket(@Nonnull Block fluid) {
switch (fluid.getType()) { return switch (fluid.getType()) {
case LAVA: case LAVA -> new ItemStack(Material.LAVA_BUCKET);
return new ItemStack(Material.LAVA_BUCKET); case WATER,
case WATER: BUBBLE_COLUMN -> new ItemStack(Material.WATER_BUCKET);
case BUBBLE_COLUMN: default ->
return new ItemStack(Material.WATER_BUCKET);
default:
// Fallback for any new liquids // Fallback for any new liquids
return new ItemStack(Material.BUCKET); new ItemStack(Material.BUCKET);
} };
} }
/** /**
@ -251,9 +249,8 @@ public class FluidPump extends SimpleSlimefunItem<BlockTicker> implements Invent
if (block.isLiquid()) { if (block.isLiquid()) {
BlockData data = block.getBlockData(); BlockData data = block.getBlockData();
if (data instanceof Levelled) { if (data instanceof Levelled levelled) {
// Check if this is a full block. // Check if this is a full block.
Levelled levelled = (Levelled) data;
return levelled.getLevel() == 0; return levelled.getLevel() == 0;
} }
} }

View File

@ -62,7 +62,7 @@ public class AnimalGrowthAccelerator extends AbstractGrowthAccelerator {
} }
private boolean isReadyToGrow(Entity n) { private boolean isReadyToGrow(Entity n) {
return n instanceof Ageable && n.isValid() && !((Ageable) n).isAdult(); return n instanceof Ageable ageable && n.isValid() && !ageable.isAdult();
} }
} }

View File

@ -1,14 +1,21 @@
package io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.accelerators; package io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.accelerators;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
import org.bukkit.Particle; import org.bukkit.Particle;
import org.bukkit.Tag; import org.bukkit.Tag;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.data.type.Sapling; import org.bukkit.block.data.type.Sapling;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup; import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup;
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils; import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
import io.github.thebusybiscuit.slimefun4.utils.itemstack.ItemStackWrapper; import io.github.thebusybiscuit.slimefun4.utils.itemstack.ItemStackWrapper;
@ -34,6 +41,7 @@ public class TreeGrowthAccelerator extends AbstractGrowthAccelerator {
// We wanna strip the Slimefun Item id here // We wanna strip the Slimefun Item id here
private static final ItemStack organicFertilizer = ItemStackWrapper.wrap(SlimefunItems.FERTILIZER); private static final ItemStack organicFertilizer = ItemStackWrapper.wrap(SlimefunItems.FERTILIZER);
@ParametersAreNonnullByDefault
public TreeGrowthAccelerator(ItemGroup itemGroup, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { public TreeGrowthAccelerator(ItemGroup itemGroup, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(itemGroup, item, recipeType, recipe); super(itemGroup, item, recipeType, recipe);
} }
@ -44,7 +52,7 @@ public class TreeGrowthAccelerator extends AbstractGrowthAccelerator {
} }
@Override @Override
protected void tick(Block b) { protected void tick(@Nonnull Block b) {
BlockMenu inv = BlockStorage.getInventory(b); BlockMenu inv = BlockStorage.getInventory(b);
if (getCharge(b.getLocation()) >= ENERGY_CONSUMPTION) { if (getCharge(b.getLocation()) >= ENERGY_CONSUMPTION) {
@ -53,9 +61,10 @@ public class TreeGrowthAccelerator extends AbstractGrowthAccelerator {
Block block = b.getRelative(x, 0, z); Block block = b.getRelative(x, 0, z);
if (Tag.SAPLINGS.isTagged(block.getType())) { if (Tag.SAPLINGS.isTagged(block.getType())) {
Sapling sapling = (Sapling) block.getBlockData(); boolean isGrowthBoosted = tryToBoostGrowth(b, inv, block);
if (sapling.getStage() < sapling.getMaximumStage() && growSapling(b, block, inv, sapling)) { if (isGrowthBoosted) {
// Finish this tick and wait for the next.
return; return;
} }
} }
@ -64,9 +73,38 @@ public class TreeGrowthAccelerator extends AbstractGrowthAccelerator {
} }
} }
private boolean growSapling(Block machine, Block block, BlockMenu inv, Sapling sapling) { @ParametersAreNonnullByDefault
private boolean tryToBoostGrowth(Block machine, BlockMenu inv, Block sapling) {
if (Slimefun.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_17)) {
// On 1.17+ we can actually simulate bonemeal :O
return applyBoneMeal(machine, sapling, inv);
} else {
Sapling saplingData = (Sapling) sapling.getBlockData();
return saplingData.getStage() < saplingData.getMaximumStage() && updateSaplingData(machine, sapling, inv, saplingData);
}
}
@ParametersAreNonnullByDefault
private boolean applyBoneMeal(Block machine, Block sapling, BlockMenu inv) {
for (int slot : getInputSlots()) { for (int slot : getInputSlots()) {
if (SlimefunUtils.isItemSimilar(inv.getItemInSlot(slot), organicFertilizer, false, false)) { if (isFertilizer(inv.getItemInSlot(slot))) {
removeCharge(machine.getLocation(), ENERGY_CONSUMPTION);
sapling.applyBoneMeal(BlockFace.UP);
inv.consumeItem(slot);
sapling.getWorld().spawnParticle(Particle.VILLAGER_HAPPY, sapling.getLocation().add(0.5D, 0.5D, 0.5D), 4, 0.1F, 0.1F, 0.1F);
return true;
}
}
return false;
}
@ParametersAreNonnullByDefault
private boolean updateSaplingData(Block machine, Block block, BlockMenu inv, Sapling sapling) {
for (int slot : getInputSlots()) {
if (isFertilizer(inv.getItemInSlot(slot))) {
removeCharge(machine.getLocation(), ENERGY_CONSUMPTION); removeCharge(machine.getLocation(), ENERGY_CONSUMPTION);
sapling.setStage(sapling.getStage() + 1); sapling.setStage(sapling.getStage() + 1);
@ -81,4 +119,8 @@ public class TreeGrowthAccelerator extends AbstractGrowthAccelerator {
return false; return false;
} }
protected boolean isFertilizer(@Nullable ItemStack item) {
return SlimefunUtils.isItemSimilar(item, organicFertilizer, false, false);
}
} }

View File

@ -128,9 +128,7 @@ public class AutoBreeder extends SlimefunItem implements InventoryBlock, EnergyN
} }
private boolean canBreed(@Nonnull Entity n) { private boolean canBreed(@Nonnull Entity n) {
if (n.isValid() && n instanceof Animals) { if (n.isValid() && n instanceof Animals animal) {
Animals animal = (Animals) n;
return animal.isAdult() && animal.canBreed() && !animal.isLoveMode(); return animal.isAdult() && animal.canBreed() && !animal.isLoveMode();
} }

View File

@ -75,8 +75,8 @@ public class ProduceCollector extends AContainer implements RecipeDisplayItem {
// Mushroom Stew from Mooshrooms // Mushroom Stew from Mooshrooms
addProduce(new AnimalProduce(new ItemStack(Material.BOWL), new ItemStack(Material.MUSHROOM_STEW), n -> { addProduce(new AnimalProduce(new ItemStack(Material.BOWL), new ItemStack(Material.MUSHROOM_STEW), n -> {
if (n instanceof MushroomCow) { if (n instanceof MushroomCow mushroomCow) {
return ((MushroomCow) n).isAdult(); return mushroomCow.isAdult();
} else { } else {
return false; return false;
} }
@ -158,8 +158,8 @@ public class ProduceCollector extends AContainer implements RecipeDisplayItem {
@ParametersAreNonnullByDefault @ParametersAreNonnullByDefault
private boolean isValidAnimal(Entity n, Predicate<LivingEntity> predicate) { private boolean isValidAnimal(Entity n, Predicate<LivingEntity> predicate) {
if (n instanceof LivingEntity) { if (n instanceof LivingEntity livingEntity) {
return predicate.test((LivingEntity) n); return predicate.test(livingEntity);
} else { } else {
return false; return false;
} }

View File

@ -44,8 +44,8 @@ public abstract class NetherStarReactor extends Reactor {
public void extraTick(@Nonnull Location l) { public void extraTick(@Nonnull Location l) {
Slimefun.runSync(() -> { Slimefun.runSync(() -> {
for (Entity entity : l.getWorld().getNearbyEntities(l, 5, 5, 5, n -> n instanceof LivingEntity && n.isValid())) { for (Entity entity : l.getWorld().getNearbyEntities(l, 5, 5, 5, n -> n instanceof LivingEntity && n.isValid())) {
if (entity instanceof LivingEntity) { if (entity instanceof LivingEntity livingEntity) {
((LivingEntity) entity).addPotionEffect(new PotionEffect(PotionEffectType.WITHER, 60, 1)); livingEntity.addPotionEffect(new PotionEffect(PotionEffectType.WITHER, 60, 1));
} }
} }
}); });

View File

@ -54,8 +54,7 @@ class ElevatorFloor {
* *
* @return The name of this floor * @return The name of this floor
*/ */
@Nonnull public @Nonnull String getName() {
public String getName() {
return name; return name;
} }
@ -64,8 +63,7 @@ class ElevatorFloor {
* *
* @return The {@link Location} of this floor * @return The {@link Location} of this floor
*/ */
@Nonnull public @Nonnull Location getLocation() {
public Location getLocation() {
return location; return location;
} }

View File

@ -68,8 +68,7 @@ public class ElevatorPlate extends SimpleSlimefunItem<BlockUseHandler> {
addItemHandler(onPlace()); addItemHandler(onPlace());
} }
@Nonnull private @Nonnull BlockPlaceHandler onPlace() {
private BlockPlaceHandler onPlace() {
return new BlockPlaceHandler(false) { return new BlockPlaceHandler(false) {
@Override @Override
@ -81,9 +80,8 @@ public class ElevatorPlate extends SimpleSlimefunItem<BlockUseHandler> {
}; };
} }
@Nonnull
@Override @Override
public BlockUseHandler getItemHandler() { public @Nonnull BlockUseHandler getItemHandler() {
return e -> { return e -> {
Block b = e.getClickedBlock().get(); Block b = e.getClickedBlock().get();
@ -93,8 +91,7 @@ public class ElevatorPlate extends SimpleSlimefunItem<BlockUseHandler> {
}; };
} }
@Nonnull public @Nonnull List<ElevatorFloor> getFloors(@Nonnull Block b) {
public List<ElevatorFloor> getFloors(@Nonnull Block b) {
LinkedList<ElevatorFloor> floors = new LinkedList<>(); LinkedList<ElevatorFloor> floors = new LinkedList<>();
int index = 0; int index = 0;
@ -209,7 +206,7 @@ public class ElevatorPlate extends SimpleSlimefunItem<BlockUseHandler> {
@ParametersAreNonnullByDefault @ParametersAreNonnullByDefault
public void openEditor(Player p, Block b) { public void openEditor(Player p, Block b) {
ChestMenu menu = new ChestMenu("Elevator Settings"); ChestMenu menu = new ChestMenu(Slimefun.getLocalization().getMessage(p, "machines.ELEVATOR.editor-title"));
menu.addItem(4, new CustomItemStack(Material.NAME_TAG, "&7Floor Name &e(Click to edit)", "", ChatColor.WHITE + ChatColors.color(BlockStorage.getLocationInfo(b.getLocation(), DATA_KEY)))); menu.addItem(4, new CustomItemStack(Material.NAME_TAG, "&7Floor Name &e(Click to edit)", "", ChatColor.WHITE + ChatColors.color(BlockStorage.getLocationInfo(b.getLocation(), DATA_KEY))));
menu.addMenuClickHandler(4, (pl, slot, item, action) -> { menu.addMenuClickHandler(4, (pl, slot, item, action) -> {

View File

@ -49,8 +49,8 @@ public class Juice extends SimpleSlimefunItem<ItemConsumptionHandler> {
ItemMeta meta = item.getItemMeta(); ItemMeta meta = item.getItemMeta();
if (meta instanceof PotionMeta) { if (meta instanceof PotionMeta potionMeta) {
effects = ((PotionMeta) meta).getCustomEffects(); effects = potionMeta.getCustomEffects();
} else { } else {
effects = new ArrayList<>(); effects = new ArrayList<>();
} }

View File

@ -107,8 +107,7 @@ public class InfusedHopper extends SimpleSlimefunItem<BlockTicker> {
} }
private boolean isValidItem(@Nonnull Location l, @Nonnull Entity entity) { private boolean isValidItem(@Nonnull Location l, @Nonnull Entity entity) {
if (entity instanceof Item && entity.isValid()) { if (entity instanceof Item item && entity.isValid()) {
Item item = (Item) entity;
// Check if the item cannot be picked up or has the "no pickup" metadata // Check if the item cannot be picked up or has the "no pickup" metadata
return item.getPickupDelay() <= 0 && !SlimefunUtils.hasNoPickupFlag(item) && item.getLocation().distanceSquared(l) > 0.25; return item.getPickupDelay() <= 0 && !SlimefunUtils.hasNoPickupFlag(item) && item.getLocation().distanceSquared(l) > 0.25;
} }

View File

@ -61,12 +61,12 @@ public class MagicalZombiePills extends SimpleSlimefunItem<EntityInteractHandler
Player p = e.getPlayer(); Player p = e.getPlayer();
if (entity instanceof ZombieVillager) { if (entity instanceof ZombieVillager zombieVillager) {
useItem(p, item); useItem(p, item);
healZombieVillager((ZombieVillager) entity, p); healZombieVillager(zombieVillager, p);
} else if (Slimefun.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_16) && entity instanceof PigZombie) { } else if (Slimefun.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_16) && entity instanceof PigZombie pigZombie) {
useItem(p, item); useItem(p, item);
healZombifiedPiglin((PigZombie) entity); healZombifiedPiglin(pigZombie);
} }
}; };
} }

View File

@ -183,9 +183,7 @@ public class EnchantmentRune extends SimpleSlimefunItem<ItemDropHandler> {
} }
private boolean findCompatibleItem(@Nonnull Entity n) { private boolean findCompatibleItem(@Nonnull Entity n) {
if (n instanceof Item) { if (n instanceof Item item) {
Item item = (Item) n;
return !isItem(item.getItemStack()); return !isItem(item.getItemStack());
} }

Some files were not shown because too many files have changed in this diff Show More