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

Conflicts:
	src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/SlimefunBootsListener.java
	src/main/java/io/github/thebusybiscuit/slimefun4/implementation/setup/ResearchSetup.java
	src/main/java/io/github/thebusybiscuit/slimefun4/implementation/setup/SlimefunItemSetup.java
This commit is contained in:
TheBusyBiscuit 2020-10-17 13:28:30 +02:00
commit 07eba9319a
267 changed files with 5978 additions and 2136 deletions

View File

@ -4,6 +4,7 @@ on:
push: push:
paths: paths:
- 'src/**' - 'src/**'
- '!src/main/resources/languages/**'
- 'pom.xml' - 'pom.xml'
jobs: jobs:
@ -15,11 +16,13 @@ jobs:
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v1 uses: actions/checkout@v2.3.3
- name: Set up JDK 1.8 - name: Set up Java JDK 11
uses: actions/setup-java@master uses: actions/setup-java@v1.4.3
with: with:
java-version: 1.8 java-version: '11'
java-package: jdk
architecture: x64
- name: Run Discord Webhook - name: Run Discord Webhook
uses: Slimefun/discord-webhook@master uses: Slimefun/discord-webhook@master
with: with:

View File

@ -4,9 +4,6 @@ on:
push: push:
branches: branches:
- master - master
pull_request:
branches:
- master
jobs: jobs:
build: build:

View File

@ -2,7 +2,8 @@
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --> <!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of contents** **Table of contents**
- [Release Candidate 17 (TBD)](#release-candidate-17-tbd) - [Release Candidate 18 (TBD)](#release-candidate-18-tbd)
- [Release Candidate 17 (17 Oct 2020)](#release-candidate-17-17-oct-2020)
- [Release Candidate 16 (07 Sep 2020)](#release-candidate-16-07-sep-2020) - [Release Candidate 16 (07 Sep 2020)](#release-candidate-16-07-sep-2020)
- [Release Candidate 15 (01 Aug 2020)](#release-candidate-15-01-aug-2020) - [Release Candidate 15 (01 Aug 2020)](#release-candidate-15-01-aug-2020)
- [Release Candidate 14 (12 Jul 2020)](#release-candidate-14-12-jul-2020) - [Release Candidate 14 (12 Jul 2020)](#release-candidate-14-12-jul-2020)
@ -22,7 +23,16 @@
<!-- END doctoc generated TOC please keep comment here to allow auto update --> <!-- END doctoc generated TOC please keep comment here to allow auto update -->
## Release Candidate 17 (TBD) ## Release Candidate 18 (TBD)
#### Additions
#### Changes
* Removed 1.13 support
#### Fixes
## Release Candidate 17 (17 Oct 2020)
#### Additions #### Additions
* Added /sf charge * Added /sf charge
@ -36,11 +46,20 @@
* (API) Added "NotConfigurable" attribute to disable configurability * (API) Added "NotConfigurable" attribute to disable configurability
* Added Elytra Cap * Added Elytra Cap
* Added Planks to Sticks recipe to the Table Saw * Added Planks to Sticks recipe to the Table Saw
* Added "slimefun.gps.bypass" permission to open GPS devices anywhere
* (API) Added custom tags for developers
* The range of the Seeker Pickaxe is now configurable
* Added Energy Connector
* Blackstone can now be turned into lava using a Crucible
* Basalt can now be turned into lava using a Crucible
* Added "Tainted Sheep" (You can dye a Sheep using Strange Nether Goo)
* Added mcMMO support/integration
#### Changes #### Changes
* Improved Auto-Updater (Multi-Threading and more) * Improved Auto-Updater (Multi-Threading and more)
* General performance improvements * General performance improvements
* /sf cheat now shows seasonal categories all year through * /sf cheat now shows seasonal categories all year through
* GPS devices now require chest-access in that area to be used
#### Fixes #### Fixes
* Fixed #2300 * Fixed #2300
@ -66,6 +85,24 @@
* Fixed #2391 * Fixed #2391
* Fixed #2403 * Fixed #2403
* Fixed #2405 * Fixed #2405
* Fixed #2412
* Fixed #2238
* Fixed #2439
* Fixed #2420
* Fixed #2422
* Fixed #2433
* Fixed #2455
* Fixed #2450
* Fixed Steel Thrusters being used to milk cows
* Fixed #2424
* Fixed #2468
* Fixed #2414
* Fixed #2454
* Fixed #2457
* Fixed #2411
* Fixed #2423
* Fixed #2452
* Fixed a dupe bug with mcMMO
## Release Candidate 16 (07 Sep 2020) ## Release Candidate 16 (07 Sep 2020)
https://thebusybiscuit.github.io/builds/TheBusyBiscuit/Slimefun4/stable/#16 https://thebusybiscuit.github.io/builds/TheBusyBiscuit/Slimefun4/stable/#16

View File

@ -94,3 +94,93 @@ Then you should be able build it via Maven using the goals `clean package`.
If you have any further questions, then please join our [Discord Support Server](https://discord.gg/slimefun) and ask your questions in the `#programming-help` channel.<br> If you have any further questions, then please join our [Discord Support Server](https://discord.gg/slimefun) and ask your questions in the `#programming-help` channel.<br>
**Note that we will not accept any bug reports from custom-compiled versions of Slimefun**. **Note that we will not accept any bug reports from custom-compiled versions of Slimefun**.
## :black_nib: Code Style guidelines
The general gist when it comes to code style: **Try to be consistent!**.<br>
Try to stay inline with the code that surrounds you, having an entire package or even a single file that's filled with plenty of different and inconsistent code styles is just hard to read or maintain. That's why we wanna make sure everyone follows these principles.
*Note that these are just guidelines, we may request changes on your pull request if we think there are changes necessary.
But we won't reject your Pull Request completely due to a few styling inconsistencies, we can always refactor code later.
But do try to follow our code style as best as you can.*
#### 1. Imports
* Don't use wildcard (`*`) imports!
* Don't import unused classes!
* Don't use static imports!
* Always use imports, even in javadocs, don't write out the full location of a class.
#### 2. Annotations
* Methods and parameters should be annotated with `@Nullable` (`javax.annotation.Nullable`) or `@Nonnull`(`javax.annotation.Nonnull`)!
* Methods that override a method must be annotated with `@Override`!
* Interfaces with only one method should be annotated using `@FunctionalInterface`!
* If you deprecate a method, add an `@deprecated` section to the javadocs explaining why you did it.
#### 3. Documentation
* Every class and every public method should have a Javadocs section assigned to it.
* New packages should have a `package-info.java` file with documentation about the package.
* Classes should have an `@author` tag.
* If there are any other relevant classes related to yours, add them using the `@see` tag.
#### 4. Unit Tests
* Try to write Unit Tests where possible.
* Unit Test classes and methods should have no access modifier, not `public`, `protected` nor `private`.
* Each Test should have a plain text `@DisplayName` annotation!
#### 5. General best-practices
* Do not use `Collection#forEach(x -> ...)`, use a proper `for (...)` loop!
* Do not create new `Random` objects, use `ThreadLocalRandom.current()` instead!
* Always declare Maps or Collections using their base type! (e.g. `List<String> list = new ArrayList<>();`)
* When doing String operations like `String#toUppercase()`, always specify `Locale.ROOT` as an argument!
* When reading or writing files, always specify the encoding using `StandardCharsets.UTF_8`!
* Do not declare multiple fields/variables on the same line! (e.g. Don't do this: `int x, y, z;`)
* Use a Logger, try to avoid `System.out.println(...)` and `Throwable#printStacktrace()`, use `Logger#log` instead!
* Do not use Exceptions to validate data, empty catch blocks are a very bad practice, use other means like a regular expression to validate data.
* If a parameter is annotated with `@Nonnull`, you should enforce this behaviour by doing `Validate.notNull(variable, "...");` and give a meaningful message about what went wrong
* Any `switch/case` should always have a `default:` case at the end.
* If you are working with a resource that must be closed, use a `try/with-resource`, this will automatically close the resource at the end. (e.g. `try (InputStream stream = ...) {`)
* Array designators should be placed behind the type, not the variable name. (e.g. `int[] myArray`)
* Enums must be compared using `==`, not with `.equals()`!
* Avoid direct string concatenation, use a `StringBuilder` instead!
* If you need both the key and the value from a Map, use `Map#entrySet()`!
#### 6. Naming conventions
* Classes should be in *PascalCase* (e.g. `MyAwesomeClass`)
* Enum constants should be in *SCREAMING_SNAKE_CASE* (e.g. `MY_ENUM_CONSTANT`)
* Constants (`static final` fields) should be in *SCREAMING_SNAKE_CASE* (e.g. `MY_CONSTANT_FIELD`)
* Variables, parameters and fields should be in *camelCase* (e.g. `myVariableOrField`)
* All methods should be in *camelCase* (e.g. `myMethod`)
* Packages must be all lowercase, consecutive words should generally be avoided. (e.g. `io.github.thebusybiscuit.slimefun4.core.something`)
#### 7. Style preferences
* Use **Spaces**, not Tabs!
* One class per file! Please don't put multiple classes into one file, this also applies to enums, make a seperate file for new classes or enums.
* Try to keep ternary operators to a minimum, only in return statements. (e.g. avoid doing this: `int y = x == null ? 1: 2`)
* Try to keep so-called "guard blocks" to a minimum. One guard block is fine but having multiple guard blocks before getting to the actual code... Well, you might wanna refactor your code there. Example:
```java
// guard block
if (something) {
return;
}
// Actual code...
```
* if/else statements should always include a bracket, please avoid one-line statements. (e.g. Avoid doing: `if (x == 0) return;`)
* We do not enforce any particular width or column limit, just try to prevent your lines from becoming too long. But please avoid line-wrapping.
* Annotations for methods or fields should never go on the same line, place them on the line above.
* Comments should never go on the same line as code! Always above or below.
* Make sure that empty lines are truly empty, they should not contain any whitespace characters.
* Empty blocks like constructors should not occupy more than one line. (e.g. `private MyClass() {}`)
* Modifiers for classes and fields must follow this order:<br>
`(public/protected/private) (abstract) (static) (final)`
* We recommend using horizontal whitespaces like this:
* In variable assignments: `int x = 123;`
* In a for-loop: `for (int i = 0; i < 10; i++) {`
* Before and after statement parenthesis: `if (x != null) {`
* Inbetween array initializers: `int[] array = { 1, 2, 3 };`
* After the double slash of a comment: `// This is a comment`
* Slimefun follows the **1TBS / OTBS** Bracket-Style standard (One true brace style):
```java
private void example(int x) {
if (x < 0) {
// x < 0
} else if (x > 0) {
// x > 0
} else {
// x == 0
}
}
```

View File

@ -32,7 +32,7 @@ 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.13.\* - 1.16.\*** | :video_game: **1.13.\* - 1.16.\*** | | **Minecraft version(s)** | :video_game: **1.14.\* - 1.16.\*** | :video_game: **1.13.\* - 1.16.\*** |
| **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: |

35
pom.xml
View File

@ -64,6 +64,10 @@
<id>worldedit-repo</id> <id>worldedit-repo</id>
<url>https://maven.sk89q.com/repo/</url> <url>https://maven.sk89q.com/repo/</url>
</repository> </repository>
<repository>
<id>codemc-repo</id>
<url>https://repo.codemc.org/repository/maven-public</url>
</repository>
<repository> <repository>
<id>placeholderapi-repo</id> <id>placeholderapi-repo</id>
<url>https://repo.extendedclip.com/content/repositories/placeholderapi/</url> <url>https://repo.extendedclip.com/content/repositories/placeholderapi/</url>
@ -262,6 +266,7 @@
<includes> <includes>
<include>*</include> <include>*</include>
<include>tags/*</include>
<include>languages/*</include> <include>languages/*</include>
</includes> </includes>
</resource> </resource>
@ -310,7 +315,7 @@
<dependency> <dependency>
<groupId>com.github.seeseemelk</groupId> <groupId>com.github.seeseemelk</groupId>
<artifactId>MockBukkit-v1.16</artifactId> <artifactId>MockBukkit-v1.16</artifactId>
<version>0.10.2</version> <version>0.13.0</version>
<scope>test</scope> <scope>test</scope>
<exclusions> <exclusions>
<exclusion> <exclusion>
@ -344,7 +349,7 @@
<dependency> <dependency>
<groupId>com.konghq</groupId> <groupId>com.konghq</groupId>
<artifactId>unirest-java</artifactId> <artifactId>unirest-java</artifactId>
<version>3.11.00</version> <version>3.11.01</version>
<scope>compile</scope> <scope>compile</scope>
<exclusions> <exclusions>
<exclusion> <exclusion>
@ -367,6 +372,32 @@
<groupId>de.schlichtherle</groupId> <groupId>de.schlichtherle</groupId>
<artifactId>truezip</artifactId> <artifactId>truezip</artifactId>
</exclusion> </exclusion>
<exclusion>
<groupId>net.java.truevfs</groupId>
<artifactId>truevfs-profile-default_2.13</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.gmail.nossr50.mcMMO</groupId>
<artifactId>mcMMO</artifactId>
<version>2.1.149</version>
<scope>provided</scope>
<exclusions>
<exclusion>
<!-- We use javax.annotation instead. Excluding this -->
<!-- prevents us from using inconsistent annotations -->
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
</exclusion>
<exclusion>
<groupId>com.sk89q.worldguard</groupId>
<artifactId>worldguard-core</artifactId>
</exclusion>
<exclusion>
<groupId>com.sk89q.worldguard</groupId>
<artifactId>worldguard-legacy</artifactId>
</exclusion>
</exclusions> </exclusions>
</dependency> </dependency>
<dependency> <dependency>

View File

@ -81,7 +81,7 @@ public class ErrorReport<T extends Throwable> {
} }
stream.println("Slimefun Data:"); stream.println("Slimefun Data:");
stream.println(" ID: " + item.getID()); stream.println(" ID: " + item.getId());
stream.println(" Inventory: " + BlockStorage.getStorage(l.getWorld()).hasInventory(l)); stream.println(" Inventory: " + BlockStorage.getStorage(l.getWorld()).hasInventory(l));
stream.println(" Data: " + BlockStorage.getBlockInfoAsJson(l)); stream.println(" Data: " + BlockStorage.getBlockInfoAsJson(l));
stream.println(); stream.println();
@ -92,7 +92,7 @@ public class ErrorReport<T extends Throwable> {
public ErrorReport(T throwable, SlimefunItem item) { public ErrorReport(T throwable, SlimefunItem item) {
this(throwable, item.getAddon(), stream -> { this(throwable, item.getAddon(), stream -> {
stream.println("SlimefunItem:"); stream.println("SlimefunItem:");
stream.println(" ID: " + item.getID()); stream.println(" ID: " + item.getId());
stream.println(" Plugin: " + (item.getAddon() == null ? "Unknown" : item.getAddon().getName())); stream.println(" Plugin: " + (item.getAddon() == null ? "Unknown" : item.getAddon().getName()));
stream.println(); stream.println();
}); });

View File

@ -14,12 +14,6 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
*/ */
public enum MinecraftVersion { public enum MinecraftVersion {
/**
* This constant represents Minecraft (Java Edition) Version 1.14
* (The Update Aquatic)
*/
MINECRAFT_1_13("1.13.x"),
/** /**
* This constant represents Minecraft (Java Edition) Version 1.14 * This constant represents Minecraft (Java Edition) Version 1.14
* (The "Village &amp; Pillage" Update) * (The "Village &amp; Pillage" Update)
@ -50,7 +44,7 @@ public enum MinecraftVersion {
*/ */
UNIT_TEST("Unit Test Environment"); UNIT_TEST("Unit Test Environment");
public static final MinecraftVersion[] values = values(); public static final MinecraftVersion[] valuesCache = values();
private final String name; private final String name;
private final String prefix; private final String prefix;

View File

@ -0,0 +1,48 @@
package io.github.thebusybiscuit.slimefun4.api.exceptions;
import javax.annotation.ParametersAreNonnullByDefault;
import org.bukkit.NamespacedKey;
import io.github.thebusybiscuit.slimefun4.utils.tags.SlimefunTag;
/**
* An {@link TagMisconfigurationException} is thrown whenever a {@link SlimefunTag}
* contains illegal, invalid or unknown values.
*
* @author TheBusyBiscuit
*
*/
public class TagMisconfigurationException extends Exception {
private static final long serialVersionUID = 5412127960821774280L;
/**
* This constructs a new {@link TagMisconfigurationException} for the given
* {@link SlimefunTag}'s {@link NamespacedKey} with the provided context.
*
* @param key
* The {@link NamespacedKey} of our {@link SlimefunTag}
* @param message
* The message to display
*/
@ParametersAreNonnullByDefault
public TagMisconfigurationException(NamespacedKey key, String message) {
super("Tag '" + key + "' has been misconfigured: " + message);
}
/**
* This constructs a new {@link TagMisconfigurationException} for the given
* {@link SlimefunTag}'s {@link NamespacedKey} with the provided context.
*
* @param key
* The {@link NamespacedKey} of our {@link SlimefunTag}
* @param cause
* The {@link Throwable} which has caused this to happen
*/
@ParametersAreNonnullByDefault
public TagMisconfigurationException(NamespacedKey key, Throwable cause) {
super("Tag '" + key + "' has been misconfigured (" + cause.getMessage() + ')', cause);
}
}

View File

@ -201,15 +201,19 @@ public class ResourceManager {
menu.addItem(47, ChestMenuUtils.getPreviousButton(p, page + 1, pages)); menu.addItem(47, ChestMenuUtils.getPreviousButton(p, page + 1, pages));
menu.addMenuClickHandler(47, (pl, slot, item, action) -> { menu.addMenuClickHandler(47, (pl, slot, item, action) -> {
if (page > 0) if (page > 0) {
scan(pl, block, page - 1); scan(pl, block, page - 1);
}
return false; return false;
}); });
menu.addItem(51, ChestMenuUtils.getNextButton(p, page + 1, pages)); menu.addItem(51, ChestMenuUtils.getNextButton(p, page + 1, pages));
menu.addMenuClickHandler(51, (pl, slot, item, action) -> { menu.addMenuClickHandler(51, (pl, slot, item, action) -> {
if (page + 1 < pages) if (page + 1 < pages) {
scan(pl, block, page + 1); scan(pl, block, page + 1);
}
return false; return false;
}); });

View File

@ -148,10 +148,12 @@ public class GPSNetwork {
int index = 0; int index = 0;
for (Location l : getTransmitters(p.getUniqueId())) { for (Location l : getTransmitters(p.getUniqueId())) {
if (index >= inventory.length) if (index >= inventory.length) {
break; break;
}
SlimefunItem sfi = BlockStorage.check(l); SlimefunItem sfi = BlockStorage.check(l);
if (sfi instanceof GPSTransmitter) { if (sfi instanceof GPSTransmitter) {
int slot = inventory[index]; int slot = inventory[index];
@ -216,8 +218,10 @@ public class GPSNetwork {
int index = 0; int index = 0;
for (Waypoint waypoint : profile.getWaypoints()) { for (Waypoint waypoint : profile.getWaypoints()) {
if (index >= inventory.length) if (index >= inventory.length) {
break; break;
}
int slot = inventory[index]; int slot = inventory[index];
Location l = waypoint.getLocation(); Location l = waypoint.getLocation();

View File

@ -92,8 +92,9 @@ public final class TeleportationManager {
@ParametersAreNonnullByDefault @ParametersAreNonnullByDefault
public int getTeleportationTime(int complexity, Location source, Location destination) { public int getTeleportationTime(int complexity, Location source, Location destination) {
if (complexity < 100) if (complexity < 100) {
return 100; return 100;
}
int speed = 50_000 + complexity * complexity; int speed = 50_000 + complexity * complexity;
return 1 + Math.min(4 * distanceSquared(source, destination) / speed, 40); return 1 + Math.min(4 * distanceSquared(source, destination) / speed, 40);

View File

@ -102,7 +102,7 @@ public final class HashedArmorpiece {
@Override @Override
public String toString() { public String toString() {
return "HashedArmorpiece {hash=" + hash + ",item=" + item.map(SlimefunItem::getID).orElse("null") + '}'; return "HashedArmorpiece {hash=" + hash + ",item=" + item.map(SlimefunItem::getId).orElse("null") + '}';
} }
} }

View File

@ -119,6 +119,17 @@ public class ItemSetting<T> {
return c.isInstance(defaultValue); return c.isInstance(defaultValue);
} }
/**
* This is an error message which should provide further context on what values
* are allowed.
*
* @return An error message which is displayed when this {@link ItemSetting} is misconfigured.
*/
@Nonnull
protected String getErrorMessage() {
return "Only '" + defaultValue.getClass().getSimpleName() + "' values are allowed!";
}
/** /**
* This method is called by a {@link SlimefunItem} which wants to load its {@link ItemSetting} * This method is called by a {@link SlimefunItem} which wants to load its {@link ItemSetting}
* from the {@link Config} file. * from the {@link Config} file.
@ -128,20 +139,33 @@ public class ItemSetting<T> {
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public void load(@Nonnull SlimefunItem item) { public void load(@Nonnull SlimefunItem item) {
SlimefunPlugin.getItemCfg().setDefaultValue(item.getID() + '.' + getKey(), getDefaultValue()); SlimefunPlugin.getItemCfg().setDefaultValue(item.getId() + '.' + getKey(), getDefaultValue());
Object configuredValue = SlimefunPlugin.getItemCfg().getValue(item.getID() + '.' + getKey()); Object configuredValue = SlimefunPlugin.getItemCfg().getValue(item.getId() + '.' + getKey());
if (defaultValue.getClass().isInstance(configuredValue)) { if (defaultValue.getClass().isInstance(configuredValue)) {
this.value = (T) configuredValue; if (validateInput((T) configuredValue)) {
this.value = (T) configuredValue;
} else {
Slimefun.getLogger().log(Level.WARNING, "Slimefun has found an invalid config setting in your Items.yml!");
Slimefun.getLogger().log(Level.WARNING, " at \"{0}.{1}\"", new Object[] { item.getId(), getKey() });
Slimefun.getLogger().log(Level.WARNING, "{0} is not a valid input!", configuredValue);
Slimefun.getLogger().log(Level.WARNING, getErrorMessage());
}
} else { } else {
this.value = defaultValue; this.value = defaultValue;
String found = configuredValue == null ? "null" : configuredValue.getClass().getSimpleName(); String found = configuredValue == null ? "null" : configuredValue.getClass().getSimpleName();
Slimefun.getLogger().log(Level.WARNING, "Slimefun has found an invalid config setting in your Items.yml!"); Slimefun.getLogger().log(Level.WARNING, "Slimefun has found an invalid config setting in your Items.yml!");
Slimefun.getLogger().log(Level.WARNING, "Please only use settings that are valid."); Slimefun.getLogger().log(Level.WARNING, "Please only use settings that are valid.");
Slimefun.getLogger().log(Level.WARNING, " at \"{0}.{1}\"", new Object[] { item.getID(), getKey() }); Slimefun.getLogger().log(Level.WARNING, " at \"{0}.{1}\"", new Object[] { item.getId(), getKey() });
Slimefun.getLogger().log(Level.WARNING, "Expected \"{0}\" but found: \"{1}\"", new Object[] { defaultValue.getClass().getSimpleName(), found }); Slimefun.getLogger().log(Level.WARNING, "Expected \"{0}\" but found: \"{1}\"", new Object[] { defaultValue.getClass().getSimpleName(), found });
} }
} }
@Override
public String toString() {
T currentValue = this.value != null ? this.value : defaultValue;
return getClass().getSimpleName() + " {" + getKey() + " = " + currentValue + " (default: " + getDefaultValue() + ")";
}
} }

View File

@ -0,0 +1,63 @@
package io.github.thebusybiscuit.slimefun4.api.items.settings;
import javax.annotation.Nonnull;
import javax.annotation.ParametersAreNonnullByDefault;
import org.apache.commons.lang.Validate;
import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting;
/**
* This variation of {@link ItemSetting} allows you to define an {@link Double} range
* and enforces this range using the {@link #validateInput(Double)} method.
*
* @author TheBusyBiscuit
*
* @see ItemSetting
* @see IntRangeSetting
*
*/
public class DoubleRangeSetting extends ItemSetting<Double> {
private final double min;
private final double max;
@ParametersAreNonnullByDefault
public DoubleRangeSetting(String key, double min, double defaultValue, double max) {
super(key, defaultValue);
Validate.isTrue(defaultValue >= min && defaultValue <= max, "The default value is not in range.");
this.min = min;
this.max = max;
}
@Nonnull
@Override
protected String getErrorMessage() {
return "Only decimal numbers from " + min + '-' + max + "(inclusive) are allowed!";
}
@Override
public boolean validateInput(Double input) {
return super.validateInput(input) && input >= min && input <= max;
}
/**
* This returns the minimum value of this {@link DoubleRangeSetting}.
*
* @return The minimum value
*/
public final double getMinimum() {
return min;
}
/**
* This returns the maximum value of this {@link DoubleRangeSetting}.
*
* @return The maximum value
*/
public final double getMaximum() {
return max;
}
}

View File

@ -0,0 +1,72 @@
package io.github.thebusybiscuit.slimefun4.api.items.settings;
import java.util.Arrays;
import java.util.stream.Collectors;
import javax.annotation.Nonnull;
import javax.annotation.ParametersAreNonnullByDefault;
import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting;
/**
* This variation of {@link ItemSetting} allows you to allow {@link Enum} constants to be
* used for {@link ItemSetting} validation.
*
* @author TheBusyBiscuit
*
* @see ItemSetting
*
*/
public class EnumSetting<T extends Enum<T>> extends ItemSetting<String> {
private final Class<T> enumClass;
@ParametersAreNonnullByDefault
public EnumSetting(String key, Class<T> enumClass, T defaultValue) {
super(key, defaultValue.name());
this.enumClass = enumClass;
}
@Nonnull
@Override
protected String getErrorMessage() {
String values = Arrays.stream(getAllowedValues()).map(Enum::name).collect(Collectors.joining(", "));
return "The following values are valid: " + values;
}
/**
* This returns an array of valid {@link Enum} values.
* This method may be overridden to further limit the allowed values.
*
* @return An array of allowed {@link Enum} constants
*/
public T[] getAllowedValues() {
return enumClass.getEnumConstants();
}
/**
* This will attempt to get the configured value as a constant of the desired {@link Enum}.
*
* @return The value as an {@link Enum} constant
*/
public T getAsEnumConstant() {
return Enum.valueOf(enumClass, getValue());
}
@Override
public boolean validateInput(String input) {
if (!super.validateInput(input)) {
return false;
} else {
for (Enum<T> value : getAllowedValues()) {
if (value.name().equals(input)) {
return true;
}
}
return false;
}
}
}

View File

@ -0,0 +1,63 @@
package io.github.thebusybiscuit.slimefun4.api.items.settings;
import javax.annotation.Nonnull;
import javax.annotation.ParametersAreNonnullByDefault;
import org.apache.commons.lang.Validate;
import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting;
/**
* This variation of {@link ItemSetting} allows you to define an {@link Integer} range
* and enforces this range using the {@link #validateInput(Integer)} method.
*
* @author TheBusyBiscuit
*
* @see ItemSetting
* @see DoubleRangeSetting
*
*/
public class IntRangeSetting extends ItemSetting<Integer> {
private final int min;
private final int max;
@ParametersAreNonnullByDefault
public IntRangeSetting(String key, int min, int defaultValue, int max) {
super(key, defaultValue);
Validate.isTrue(defaultValue >= min && defaultValue <= max, "The default value is not in range.");
this.min = min;
this.max = max;
}
@Nonnull
@Override
protected String getErrorMessage() {
return "Only whole numbers from " + min + '-' + max + "(inclusive) are allowed!";
}
@Override
public boolean validateInput(Integer input) {
return super.validateInput(input) && input >= min && input <= max;
}
/**
* This returns the minimum value of this {@link IntRangeSetting}.
*
* @return The minimum value
*/
public final int getMinimum() {
return min;
}
/**
* This returns the maximum value of this {@link IntRangeSetting}.
*
* @return The maximum value
*/
public final int getMaximum() {
return max;
}
}

View File

@ -0,0 +1,83 @@
package io.github.thebusybiscuit.slimefun4.api.items.settings;
import java.util.List;
import java.util.stream.Collectors;
import javax.annotation.Nonnull;
import javax.annotation.ParametersAreNonnullByDefault;
import org.bukkit.Material;
import org.bukkit.Tag;
import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting;
/**
* This variation of {@link ItemSetting} allows you to define a default {@link Tag}.
* The {@link Tag} will be translated into a {@link String} {@link List} which the user
* can then configure as they wish.
*
* It also validates all inputs to be a valid {@link Material}.
*
* @author TheBusyBiscuit
*
* @see ItemSetting
*
*/
public class MaterialTagSetting extends ItemSetting<List<String>> {
private final Tag<Material> defaultTag;
@ParametersAreNonnullByDefault
public MaterialTagSetting(String key, Tag<Material> defaultTag) {
super(key, getAsStringList(defaultTag));
this.defaultTag = defaultTag;
}
/**
* This {@link Tag} holds the default values for this {@link MaterialTagSetting}.
*
* @return The default {@link Tag}
*/
@Nonnull
public Tag<Material> getDefaultTag() {
return defaultTag;
}
@Nonnull
@Override
protected String getErrorMessage() {
return "This List can only contain Materials in the format of e.g. REDSTONE_BLOCK";
}
@Override
public boolean validateInput(List<String> input) {
if (super.validateInput(input)) {
for (String value : input) {
Material material = Material.matchMaterial(value);
// This value is not a valid material, the setting is not valid.
if (material == null) {
return false;
}
}
return true;
} else {
return false;
}
}
/**
* Internal method to turn a {@link Tag} into a {@link List} of {@link String Strings}.
*
* @param tag
* Our {@link Tag}
* @return The {@link String} {@link List}
*/
@Nonnull
private static List<String> getAsStringList(@Nonnull Tag<Material> tag) {
return tag.getValues().stream().map(Material::name).collect(Collectors.toList());
}
}

View File

@ -0,0 +1,4 @@
/**
* This package contains various sub classes of {@link io.github.thebusybiscuit.slimefun4.api.items.ItemSetting}.
*/
package io.github.thebusybiscuit.slimefun4.api.items.settings;

View File

@ -28,13 +28,14 @@ import io.github.thebusybiscuit.slimefun4.implementation.listeners.BackpackListe
*/ */
public class PlayerBackpack { public class PlayerBackpack {
private static final String CONFIG_PREFIX = "backpacks.";
private final PlayerProfile profile; private final PlayerProfile profile;
private final int id; private final int id;
private final Config cfg; private final Config cfg;
private Inventory inventory; private Inventory inventory;
private int size; private int size;
private static final String CONFIG_PREFIX = "backpacks.";
/** /**
* This constructor loads an existing Backpack * This constructor loads an existing Backpack

View File

@ -4,6 +4,8 @@ import java.util.Optional;
import java.util.OptionalInt; import java.util.OptionalInt;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import javax.annotation.Nonnull;
import io.github.thebusybiscuit.slimefun4.utils.PatternUtils; import io.github.thebusybiscuit.slimefun4.utils.PatternUtils;
import org.bukkit.Keyed; import org.bukkit.Keyed;
import org.bukkit.NamespacedKey; import org.bukkit.NamespacedKey;
@ -27,10 +29,11 @@ public class StatusEffect implements Keyed {
private final NamespacedKey key; private final NamespacedKey key;
public StatusEffect(NamespacedKey key) { public StatusEffect(@Nonnull NamespacedKey key) {
this.key = key; this.key = key;
} }
@Nonnull
@Override @Override
public NamespacedKey getKey() { public NamespacedKey getKey() {
return key; return key;
@ -48,7 +51,7 @@ public class StatusEffect implements Keyed {
* @param unit * @param unit
* The {@link TimeUnit} for the given duration * The {@link TimeUnit} for the given duration
*/ */
public void add(Player p, int duration, TimeUnit unit) { public void add(@Nonnull Player p, int duration, @Nonnull TimeUnit unit) {
add(p, 1, duration, unit); add(p, 1, duration, unit);
} }
@ -64,7 +67,7 @@ public class StatusEffect implements Keyed {
* @param unit * @param unit
* The {@link TimeUnit} for the given duration * The {@link TimeUnit} for the given duration
*/ */
public void add(Player p, int level, int duration, TimeUnit unit) { public void add(@Nonnull Player p, int level, int duration, @Nonnull TimeUnit unit) {
PersistentDataAPI.setString(p, getKey(), level + ";" + System.currentTimeMillis() + unit.toMillis(duration)); PersistentDataAPI.setString(p, getKey(), level + ";" + System.currentTimeMillis() + unit.toMillis(duration));
} }
@ -77,7 +80,7 @@ public class StatusEffect implements Keyed {
* @param level * @param level
* The level of this effect * The level of this effect
*/ */
public void addPermanent(Player p, int level) { public void addPermanent(@Nonnull Player p, int level) {
PersistentDataAPI.setString(p, getKey(), level + ";0"); PersistentDataAPI.setString(p, getKey(), level + ";0");
} }
@ -91,7 +94,7 @@ public class StatusEffect implements Keyed {
* The {@link Player} to check for * The {@link Player} to check for
* @return Whether this {@link StatusEffect} is currently applied * @return Whether this {@link StatusEffect} is currently applied
*/ */
public boolean isPresent(Player p) { public boolean isPresent(@Nonnull Player p) {
Optional<String> optional = PersistentDataAPI.getOptionalString(p, getKey()); Optional<String> optional = PersistentDataAPI.getOptionalString(p, getKey());
if (optional.isPresent()) { if (optional.isPresent()) {
@ -104,8 +107,9 @@ public class StatusEffect implements Keyed {
clear(p); clear(p);
return false; return false;
} }
} else } else {
return false; return false;
}
} }
/** /**
@ -116,15 +120,16 @@ public class StatusEffect implements Keyed {
* The {@link Player} to check for * The {@link Player} to check for
* @return An {@link OptionalInt} that describes the result * @return An {@link OptionalInt} that describes the result
*/ */
public OptionalInt getLevel(Player p) { @Nonnull
public OptionalInt getLevel(@Nonnull Player p) {
Optional<String> optional = PersistentDataAPI.getOptionalString(p, getKey()); Optional<String> optional = PersistentDataAPI.getOptionalString(p, getKey());
if (optional.isPresent()) { if (optional.isPresent()) {
String[] data = PatternUtils.SEMICOLON.split(optional.get()); String[] data = PatternUtils.SEMICOLON.split(optional.get());
return OptionalInt.of(Integer.parseInt(data[0])); return OptionalInt.of(Integer.parseInt(data[0]));
} else {
} else
return OptionalInt.empty(); return OptionalInt.empty();
}
} }
/** /**
@ -133,7 +138,7 @@ public class StatusEffect implements Keyed {
* @param p * @param p
* The {@link Player} to clear it from * The {@link Player} to clear it from
*/ */
public void clear(Player p) { public void clear(@Nonnull Player p) {
PersistentDataAPI.remove(p, getKey()); PersistentDataAPI.remove(p, getKey());
} }

View File

@ -11,6 +11,9 @@ import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import javax.annotation.Nonnull;
import org.apache.commons.lang.Validate;
import org.bukkit.Server; import org.bukkit.Server;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType; import org.bukkit.entity.EntityType;
@ -19,14 +22,12 @@ import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.cscorelib2.collections.KeyMap; import io.github.thebusybiscuit.cscorelib2.collections.KeyMap;
import io.github.thebusybiscuit.cscorelib2.config.Config; import io.github.thebusybiscuit.cscorelib2.config.Config;
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
import io.github.thebusybiscuit.slimefun4.api.geo.GEOResource; import io.github.thebusybiscuit.slimefun4.api.geo.GEOResource;
import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile; import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile;
import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideImplementation; import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideImplementation;
import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideLayout; import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideLayout;
import io.github.thebusybiscuit.slimefun4.core.multiblocks.MultiBlock; import io.github.thebusybiscuit.slimefun4.core.multiblocks.MultiBlock;
import io.github.thebusybiscuit.slimefun4.core.researching.Research; import io.github.thebusybiscuit.slimefun4.core.researching.Research;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.guide.BookSlimefunGuide; import io.github.thebusybiscuit.slimefun4.implementation.guide.BookSlimefunGuide;
import io.github.thebusybiscuit.slimefun4.implementation.guide.CheatSheetSlimefunGuide; import io.github.thebusybiscuit.slimefun4.implementation.guide.CheatSheetSlimefunGuide;
import io.github.thebusybiscuit.slimefun4.implementation.guide.ChestSlimefunGuide; import io.github.thebusybiscuit.slimefun4.implementation.guide.ChestSlimefunGuide;
@ -47,7 +48,7 @@ import me.mrCookieSlime.Slimefun.api.inventory.UniversalBlockMenu;
* @author TheBusyBiscuit * @author TheBusyBiscuit
* *
*/ */
public class SlimefunRegistry { public final class SlimefunRegistry {
private final Map<String, SlimefunItem> slimefunIds = new HashMap<>(); private final Map<String, SlimefunItem> slimefunIds = new HashMap<>();
private final List<SlimefunItem> slimefunItems = new ArrayList<>(); private final List<SlimefunItem> slimefunItems = new ArrayList<>();
@ -86,7 +87,9 @@ public class SlimefunRegistry {
private final Map<String, ItemStack> automatedCraftingChamberRecipes = new HashMap<>(); private final Map<String, ItemStack> automatedCraftingChamberRecipes = new HashMap<>();
public void load(Config cfg) { public void load(@Nonnull Config cfg) {
Validate.notNull(cfg, "The Config cannot be null!");
boolean showVanillaRecipes = cfg.getBoolean("guide.show-vanilla-recipes"); boolean showVanillaRecipes = cfg.getBoolean("guide.show-vanilla-recipes");
layouts.put(SlimefunGuideLayout.CHEST, new ChestSlimefunGuide(showVanillaRecipes)); layouts.put(SlimefunGuideLayout.CHEST, new ChestSlimefunGuide(showVanillaRecipes));
@ -95,7 +98,7 @@ public class SlimefunRegistry {
researchRanks.addAll(cfg.getStringList("research-ranks")); researchRanks.addAll(cfg.getStringList("research-ranks"));
backwardsCompatibility = cfg.getBoolean("options.backwards-compatibility") || SlimefunPlugin.getMinecraftVersion().isBefore(MinecraftVersion.MINECRAFT_1_14); backwardsCompatibility = cfg.getBoolean("options.backwards-compatibility");
freeCreativeResearches = cfg.getBoolean("researches.free-in-creative-mode"); freeCreativeResearches = cfg.getBoolean("researches.free-in-creative-mode");
researchFireworks = cfg.getBoolean("researches.enable-fireworks"); researchFireworks = cfg.getBoolean("researches.enable-fireworks");
logDuplicateBlockEntries = cfg.getBoolean("options.log-duplicate-block-entries"); logDuplicateBlockEntries = cfg.getBoolean("options.log-duplicate-block-entries");

View File

@ -66,6 +66,12 @@ public interface EnergyNetComponent extends ItemAttribute {
*/ */
default int getCharge(@Nonnull Location l) { default int getCharge(@Nonnull Location l) {
Validate.notNull(l, "Location was null!"); Validate.notNull(l, "Location was null!");
// Emergency fallback, this cannot hold a charge, so we'll just return zero
if (!isChargeable()) {
return 0;
}
String charge = BlockStorage.getLocationInfo(l, "energy-charge"); String charge = BlockStorage.getLocationInfo(l, "energy-charge");
if (charge != null) { if (charge != null) {

View File

@ -13,7 +13,6 @@ import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataType; import org.bukkit.persistence.PersistentDataType;
import io.github.thebusybiscuit.cscorelib2.chat.ChatColors; import io.github.thebusybiscuit.cscorelib2.chat.ChatColors;
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.utils.PatternUtils; import io.github.thebusybiscuit.slimefun4.utils.PatternUtils;
import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.ChatColor;
@ -39,9 +38,7 @@ final class RechargeableHelper {
BigDecimal decimal = BigDecimal.valueOf(charge).setScale(2, RoundingMode.HALF_UP); BigDecimal decimal = BigDecimal.valueOf(charge).setScale(2, RoundingMode.HALF_UP);
float value = decimal.floatValue(); float value = decimal.floatValue();
if (SlimefunPlugin.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_14)) { meta.getPersistentDataContainer().set(CHARGE_KEY, PersistentDataType.FLOAT, value);
meta.getPersistentDataContainer().set(CHARGE_KEY, PersistentDataType.FLOAT, value);
}
List<String> lore = meta.hasLore() ? meta.getLore() : new ArrayList<>(); List<String> lore = meta.hasLore() ? meta.getLore() : new ArrayList<>();
for (int i = 0; i < lore.size(); i++) { for (int i = 0; i < lore.size(); i++) {
@ -59,13 +56,11 @@ final class RechargeableHelper {
} }
static float getCharge(@Nonnull ItemMeta meta) { static float getCharge(@Nonnull ItemMeta meta) {
if (SlimefunPlugin.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_14)) { Float value = meta.getPersistentDataContainer().get(CHARGE_KEY, PersistentDataType.FLOAT);
Float value = meta.getPersistentDataContainer().get(CHARGE_KEY, PersistentDataType.FLOAT);
// If persistent data is available, we just return this value // If persistent data is available, we just return this value
if (value != null) { if (value != null) {
return value; return value;
}
} }
// If no persistent data exists, we will just fall back to the lore // If no persistent data exists, we will just fall back to the lore

View File

@ -99,7 +99,7 @@ class SlimefunTabCompleter implements TabCompleter {
List<String> list = new ArrayList<>(items.size()); List<String> list = new ArrayList<>(items.size());
for (SlimefunItem item : items) { for (SlimefunItem item : items) {
list.add(item.getID()); list.add(item.getId());
} }
return list; return list;

View File

@ -49,8 +49,9 @@ class ResearchCommand extends SubCommand {
} else { } else {
SlimefunPlugin.getLocalization().sendMessage(sender, "messages.not-online", true, msg -> msg.replace(PLACEHOLDER_PLAYER, args[1])); SlimefunPlugin.getLocalization().sendMessage(sender, "messages.not-online", true, msg -> msg.replace(PLACEHOLDER_PLAYER, args[1]));
} }
} else } else {
SlimefunPlugin.getLocalization().sendMessage(sender, "messages.no-permission", true); SlimefunPlugin.getLocalization().sendMessage(sender, "messages.no-permission", true);
}
} else { } else {
SlimefunPlugin.getLocalization().sendMessage(sender, "messages.usage", true, msg -> msg.replace("%usage%", "/sf research <Player> <all/reset/Research>")); SlimefunPlugin.getLocalization().sendMessage(sender, "messages.usage", true, msg -> msg.replace("%usage%", "/sf research <Player> <all/reset/Research>"));
} }

View File

@ -29,8 +29,9 @@ class StatsCommand extends SubCommand {
} else { } else {
SlimefunPlugin.getLocalization().sendMessage(sender, "messages.not-online", true, msg -> msg.replace("%player%", args[1])); SlimefunPlugin.getLocalization().sendMessage(sender, "messages.not-online", true, msg -> msg.replace("%player%", args[1]));
} }
} else } else {
SlimefunPlugin.getLocalization().sendMessage(sender, "messages.no-permission", true); SlimefunPlugin.getLocalization().sendMessage(sender, "messages.no-permission", true);
}
} else if (sender instanceof Player) { } else if (sender instanceof Player) {
PlayerProfile.get((Player) sender, profile -> profile.sendStats(sender)); PlayerProfile.get((Player) sender, profile -> profile.sendStats(sender));
} else { } else {

View File

@ -78,15 +78,20 @@ public final class SlimefunGuide {
} }
public static void openCategory(PlayerProfile profile, Category category, SlimefunGuideLayout layout, int selectedPage) { public static void openCategory(PlayerProfile profile, Category category, SlimefunGuideLayout layout, int selectedPage) {
if (category == null) if (category == null) {
return; return;
}
SlimefunPlugin.getRegistry().getGuideLayout(layout).openCategory(profile, category, selectedPage); SlimefunPlugin.getRegistry().getGuideLayout(layout).openCategory(profile, category, selectedPage);
} }
public static void openSearch(PlayerProfile profile, String input, boolean survival, boolean addToHistory) { public static void openSearch(PlayerProfile profile, String input, boolean survival, boolean addToHistory) {
SlimefunGuideImplementation layout = SlimefunPlugin.getRegistry().getGuideLayout(SlimefunGuideLayout.CHEST); SlimefunGuideImplementation layout = SlimefunPlugin.getRegistry().getGuideLayout(SlimefunGuideLayout.CHEST);
if (!survival)
if (!survival) {
layout = SlimefunPlugin.getRegistry().getGuideLayout(SlimefunGuideLayout.CHEAT_SHEET); layout = SlimefunPlugin.getRegistry().getGuideLayout(SlimefunGuideLayout.CHEAT_SHEET);
}
layout.openSearch(profile, input, addToHistory); layout.openSearch(profile, input, addToHistory);
} }

View File

@ -31,6 +31,6 @@ public enum SlimefunGuideLayout {
*/ */
CHEAT_SHEET; CHEAT_SHEET;
public static final SlimefunGuideLayout[] values = values(); public static final SlimefunGuideLayout[] valuesCache = values();
} }

View File

@ -98,7 +98,7 @@ class GuideLayoutOption implements SlimefunGuideOption<SlimefunGuideLayout> {
@Override @Override
public Optional<SlimefunGuideLayout> getSelectedOption(Player p, ItemStack guide) { public Optional<SlimefunGuideLayout> getSelectedOption(Player p, ItemStack guide) {
for (SlimefunGuideLayout layout : SlimefunGuideLayout.values) { for (SlimefunGuideLayout layout : SlimefunGuideLayout.valuesCache) {
if (SlimefunUtils.isItemSimilar(guide, SlimefunGuide.getItem(layout), true, false)) { if (SlimefunUtils.isItemSimilar(guide, SlimefunGuide.getItem(layout), true, false)) {
return Optional.of(layout); return Optional.of(layout);
} }

View File

@ -12,7 +12,6 @@ import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.cscorelib2.item.CustomItem; import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuide; import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuide;
import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideLayout; import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideLayout;
import io.github.thebusybiscuit.slimefun4.core.services.localization.Language; import io.github.thebusybiscuit.slimefun4.core.services.localization.Language;
@ -41,11 +40,8 @@ public final class SlimefunGuideSettings {
static { static {
options.add(new GuideLayoutOption()); options.add(new GuideLayoutOption());
options.add(new FireworksOption());
if (SlimefunPlugin.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_14)) { options.add(new PlayerLanguageOption());
options.add(new FireworksOption());
options.add(new PlayerLanguageOption());
}
} }
private SlimefunGuideSettings() {} private SlimefunGuideSettings() {}

View File

@ -1,6 +1,9 @@
package io.github.thebusybiscuit.slimefun4.core.handlers; package io.github.thebusybiscuit.slimefun4.core.handlers;
import java.util.Arrays; import java.util.Arrays;
import java.util.List;
import javax.annotation.Nonnull;
import org.apache.commons.lang.Validate; import org.apache.commons.lang.Validate;
import org.bukkit.Material; import org.bukkit.Material;
@ -10,7 +13,6 @@ import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.type.GlassPane; import org.bukkit.block.data.type.GlassPane;
import io.github.thebusybiscuit.cscorelib2.collections.LoopIterator; import io.github.thebusybiscuit.cscorelib2.collections.LoopIterator;
import io.github.thebusybiscuit.cscorelib2.materials.MaterialCollection;
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion; import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.items.blocks.RainbowBlock; import io.github.thebusybiscuit.slimefun4.implementation.items.blocks.RainbowBlock;
@ -34,18 +36,22 @@ public class RainbowTickHandler extends BlockTicker {
private final boolean glassPanes; private final boolean glassPanes;
private Material material; private Material material;
public RainbowTickHandler(Material... materials) { public RainbowTickHandler(@Nonnull List<Material> materials) {
Validate.noNullElements(materials, "A RainbowTicker cannot have a Material that is null!"); Validate.noNullElements(materials, "A RainbowTicker cannot have a Material that is null!");
if (materials.length == 0) { if (materials.isEmpty()) {
throw new IllegalArgumentException("A RainbowTicker must have at least one Material associated with it!"); throw new IllegalArgumentException("A RainbowTicker must have at least one Material associated with it!");
} }
glassPanes = containsGlassPanes(materials); glassPanes = containsGlassPanes(materials);
iterator = new LoopIterator<>(Arrays.asList(materials)); iterator = new LoopIterator<>(materials);
material = iterator.next(); material = iterator.next();
} }
public RainbowTickHandler(Material... materials) {
this(Arrays.asList(materials));
}
/** /**
* This method checks whether a given {@link Material} array contains any {@link Material} * This method checks whether a given {@link Material} array contains any {@link Material}
* that would result in a {@link GlassPane} {@link BlockData}. * that would result in a {@link GlassPane} {@link BlockData}.
@ -57,7 +63,7 @@ public class RainbowTickHandler extends BlockTicker {
* *
* @return Whether the array contained any {@link GlassPane} materials * @return Whether the array contained any {@link GlassPane} materials
*/ */
private boolean containsGlassPanes(Material[] materials) { private boolean containsGlassPanes(@Nonnull List<Material> materials) {
if (SlimefunPlugin.getMinecraftVersion() == MinecraftVersion.UNIT_TEST) { if (SlimefunPlugin.getMinecraftVersion() == MinecraftVersion.UNIT_TEST) {
// BlockData is not available to us during Unit Tests :/ // BlockData is not available to us during Unit Tests :/
return false; return false;
@ -75,10 +81,6 @@ public class RainbowTickHandler extends BlockTicker {
return false; return false;
} }
public RainbowTickHandler(MaterialCollection collection) {
this(collection.getAsArray());
}
@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) {

View File

@ -41,10 +41,8 @@ public class MultiBlock {
SUPPORTED_TAGS.add(Tag.LOGS); SUPPORTED_TAGS.add(Tag.LOGS);
SUPPORTED_TAGS.add(Tag.WOODEN_TRAPDOORS); SUPPORTED_TAGS.add(Tag.WOODEN_TRAPDOORS);
SUPPORTED_TAGS.add(Tag.WOODEN_SLABS); SUPPORTED_TAGS.add(Tag.WOODEN_SLABS);
SUPPORTED_TAGS.add(Tag.WOODEN_FENCES);
if (SlimefunPlugin.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_14)) {
SUPPORTED_TAGS.add(Tag.WOODEN_FENCES);
}
if (SlimefunPlugin.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_16)) { if (SlimefunPlugin.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_16)) {
SUPPORTED_TAGS.add(Tag.FIRE); SUPPORTED_TAGS.add(Tag.FIRE);
} }
@ -119,7 +117,7 @@ public class MultiBlock {
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hash(item.getID(), blocks, trigger, isSymmetric); return Objects.hash(item.getId(), blocks, trigger, isSymmetric);
} }
private boolean compareBlocks(Material a, @Nullable Material b) { private boolean compareBlocks(Material a, @Nullable Material b) {
@ -161,6 +159,6 @@ public class MultiBlock {
@Override @Override
public String toString() { public String toString() {
return "MultiBlock (" + item.getID() + ") {" + Arrays.toString(blocks) + "}"; return "MultiBlock (" + item.getId() + ") {" + Arrays.toString(blocks) + "}";
} }
} }

View File

@ -18,10 +18,10 @@ import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.cscorelib2.blocks.BlockPosition; import io.github.thebusybiscuit.cscorelib2.blocks.BlockPosition;
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils; import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
import io.github.thebusybiscuit.slimefun4.utils.itemstack.ItemStackWrapper; import io.github.thebusybiscuit.slimefun4.utils.itemstack.ItemStackWrapper;
import io.github.thebusybiscuit.slimefun4.utils.tags.SlimefunTag;
import io.papermc.lib.PaperLib; import io.papermc.lib.PaperLib;
import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config; import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config;
import me.mrCookieSlime.Slimefun.api.BlockStorage; import me.mrCookieSlime.Slimefun.api.BlockStorage;
@ -54,6 +54,10 @@ final class CargoUtils {
Material type = block.getType(); Material type = block.getType();
if (SlimefunTag.SHULKER_BOXES.isTagged(type)) {
return true;
}
switch (type) { switch (type) {
case CHEST: case CHEST:
case TRAPPED_CHEST: case TRAPPED_CHEST:
@ -62,28 +66,13 @@ final class CargoUtils {
case DROPPER: case DROPPER:
case HOPPER: case HOPPER:
case BREWING_STAND: case BREWING_STAND:
case SHULKER_BOX: case BARREL:
case BLAST_FURNACE:
case SMOKER:
return true; return true;
default: default:
break; return false;
} }
if (type.name().endsWith("_SHULKER_BOX")) {
return true;
}
if (SlimefunPlugin.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_14)) {
switch (type) {
case BARREL:
case BLAST_FURNACE:
case SMOKER:
return true;
default:
break;
}
}
return false;
} }
static int[] getInputSlotRange(@Nonnull Inventory inv, @Nullable ItemStack item) { static int[] getInputSlotRange(@Nonnull Inventory inv, @Nullable ItemStack item) {

View File

@ -70,6 +70,7 @@ public class EnergyNet extends Network {
return null; return null;
} else { } else {
switch (component.getEnergyComponentType()) { switch (component.getEnergyComponentType()) {
case CONNECTOR:
case CAPACITOR: case CAPACITOR:
return NetworkComponent.CONNECTOR; return NetworkComponent.CONNECTOR;
case CONSUMER: case CONSUMER:
@ -272,6 +273,20 @@ public class EnergyNet extends Network {
return null; return null;
} }
/**
* This attempts to get an {@link EnergyNet} from a given {@link Location}.
* If no suitable {@link EnergyNet} could be found, {@code null} will be returned.
*
* @param l
* The target {@link Location}
*
* @return The {@link EnergyNet} at that {@link Location}, or {@code null}
*/
@Nullable
public static EnergyNet getNetworkFromLocation(@Nonnull Location l) {
return SlimefunPlugin.getNetworkManager().getNetworkFromLocation(l, EnergyNet.class).orElse(null);
}
/** /**
* This attempts to get an {@link EnergyNet} from a given {@link Location}. * This attempts to get an {@link EnergyNet} from a given {@link Location}.
* If no suitable {@link EnergyNet} could be found, a new one will be created. * If no suitable {@link EnergyNet} could be found, a new one will be created.

View File

@ -4,6 +4,7 @@ import org.bukkit.block.Block;
import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetComponent; import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetComponent;
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.Capacitor; import io.github.thebusybiscuit.slimefun4.implementation.items.electric.Capacitor;
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.EnergyConnector;
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.reactors.Reactor; import io.github.thebusybiscuit.slimefun4.implementation.items.electric.reactors.Reactor;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AContainer; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AContainer;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AGenerator; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AGenerator;
@ -13,6 +14,7 @@ import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AGenerator;
* can have. * can have.
* *
* @author TheBusyBiscuit * @author TheBusyBiscuit
* @author Linox
* *
* @see EnergyNetComponent * @see EnergyNetComponent
* @see EnergyNet * @see EnergyNet
@ -38,6 +40,12 @@ public enum EnergyNetComponentType {
*/ */
CONSUMER, CONSUMER,
/**
* A Connector transmits energy through the network.
* Also see: {@link EnergyConnector}
*/
CONNECTOR,
/** /**
* A fallback value to use when a {@link Block} cannot be classified as any of the * A fallback value to use when a {@link Block} cannot be classified as any of the
* other options. * other options.

View File

@ -11,9 +11,6 @@ import org.bukkit.block.TileState;
import org.bukkit.persistence.PersistentDataHolder; import org.bukkit.persistence.PersistentDataHolder;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
/** /**
* The {@link BlockDataService} is similar to the {@link CustomItemDataService}, * The {@link BlockDataService} is similar to the {@link CustomItemDataService},
* it is responsible for storing NBT data inside a {@link TileState}. * it is responsible for storing NBT data inside a {@link TileState}.
@ -83,9 +80,8 @@ public class BlockDataService implements PersistentDataService, Keyed {
* @return Whether the given {@link Material} is considered a Tile Entity * @return Whether the given {@link Material} is considered a Tile Entity
*/ */
public boolean isTileEntity(Material type) { public boolean isTileEntity(Material type) {
if (type == null || !SlimefunPlugin.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_14)) { if (type == null || type.isAir()) {
// We can only store data on Tile Entities in 1.14+ // Cannot store data on air
// So we will just return false here in that case.
return false; return false;
} }

View File

@ -10,8 +10,6 @@ import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import io.github.thebusybiscuit.cscorelib2.config.Config; import io.github.thebusybiscuit.cscorelib2.config.Config;
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
@ -64,9 +62,9 @@ public class CustomTextureService {
for (SlimefunItem item : items) { for (SlimefunItem item : items) {
if (item != null) { if (item != null) {
config.setDefaultValue(item.getID(), 0); config.setDefaultValue(item.getId(), 0);
if (config.getInt(item.getID()) != 0) { if (config.getInt(item.getId()) != 0) {
modified = true; modified = true;
} }
} }
@ -101,10 +99,7 @@ public class CustomTextureService {
public void setTexture(@Nonnull ItemMeta im, @Nonnull String id) { public void setTexture(@Nonnull ItemMeta im, @Nonnull String id) {
int data = getModelData(id); int data = getModelData(id);
im.setCustomModelData(data == 0 ? null : data);
if (SlimefunPlugin.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_14)) {
im.setCustomModelData(data == 0 ? null : data);
}
} }
} }

View File

@ -48,12 +48,7 @@ public class MetricsService {
private boolean hasDownloadedUpdate = false; private boolean hasDownloadedUpdate = false;
static { static {
Unirest.config() Unirest.config().concurrency(2, 1).setDefaultHeader("User-Agent", "MetricsModule Auto-Updater").setDefaultHeader("Accept", "application/vnd.github.v3+json").enableCookieManagement(false).cookieSpec("ignoreCookies");
.concurrency(2, 1)
.setDefaultHeader("User-Agent", "MetricsModule Auto-Updater")
.setDefaultHeader("Accept", "application/vnd.github.v3+json")
.enableCookieManagement(false)
.cookieSpec("ignoreCookies");
} }
public MetricsService(@Nonnull SlimefunPlugin plugin) { public MetricsService(@Nonnull SlimefunPlugin plugin) {
@ -221,7 +216,7 @@ public class MetricsService {
return true; return true;
} }
} catch (UnirestException e) { } catch (UnirestException e) {
plugin.getLogger().log(Level.WARNING, "Failed to fetch the latest jar file from the builds page. Perhaps GitHub is down?"); plugin.getLogger().log(Level.WARNING, "Failed to fetch the latest jar file from the builds page. Perhaps GitHub is down? Response: {0}", e.getMessage());
} catch (IOException e) { } catch (IOException e) {
plugin.getLogger().log(Level.WARNING, "Failed to replace the old metric file with the new one. Please do this manually! Error: {0}", e.getMessage()); plugin.getLogger().log(Level.WARNING, "Failed to replace the old metric file with the new one. Please do this manually! Error: {0}", e.getMessage());
} }

View File

@ -85,7 +85,7 @@ public class PerWorldSettingsService {
return false; return false;
} }
return !items.contains(item.getID()); return !items.contains(item.getId());
} }
/** /**
@ -105,9 +105,9 @@ public class PerWorldSettingsService {
Set<String> items = disabledItems.computeIfAbsent(world.getUID(), id -> loadWorldFromConfig(world)); Set<String> items = disabledItems.computeIfAbsent(world.getUID(), id -> loadWorldFromConfig(world));
if (enabled) { if (enabled) {
items.remove(item.getID()); items.remove(item.getId());
} else { } else {
items.add(item.getID()); items.add(item.getId());
} }
} }
@ -178,7 +178,7 @@ public class PerWorldSettingsService {
for (SlimefunItem item : SlimefunPlugin.getRegistry().getEnabledSlimefunItems()) { for (SlimefunItem item : SlimefunPlugin.getRegistry().getEnabledSlimefunItems()) {
if (item != null) { if (item != null) {
String addon = item.getAddon().getName().toLowerCase(Locale.ROOT); String addon = item.getAddon().getName().toLowerCase(Locale.ROOT);
config.setValue(addon + '.' + item.getID(), !items.contains(item.getID())); config.setValue(addon + '.' + item.getId(), !items.contains(item.getId()));
} }
} }
@ -222,7 +222,7 @@ public class PerWorldSettingsService {
if (item != null) { if (item != null) {
String addon = item.getAddon().getName().toLowerCase(Locale.ROOT); String addon = item.getAddon().getName().toLowerCase(Locale.ROOT);
config.setDefaultValue(addon + ".enabled", true); config.setDefaultValue(addon + ".enabled", true);
config.setDefaultValue(addon + '.' + item.getID(), true); config.setDefaultValue(addon + '.' + item.getId(), true);
// Whether the entire addon has been disabled // Whether the entire addon has been disabled
boolean isAddonDisabled = config.getBoolean(addon + ".enabled"); boolean isAddonDisabled = config.getBoolean(addon + ".enabled");
@ -232,8 +232,8 @@ public class PerWorldSettingsService {
blacklist.add(worldName); blacklist.add(worldName);
} }
if (!isAddonDisabled || !config.getBoolean(addon + '.' + item.getID())) { if (!isAddonDisabled || !config.getBoolean(addon + '.' + item.getId())) {
items.add(item.getID()); items.add(item.getId());
} }
} }
} }

View File

@ -41,12 +41,12 @@ public class PermissionsService {
public void register(@Nonnull Iterable<SlimefunItem> items, boolean save) { public void register(@Nonnull Iterable<SlimefunItem> items, boolean save) {
for (SlimefunItem item : items) { for (SlimefunItem item : items) {
if (item != null) { if (item != null) {
String path = item.getID() + ".permission"; String path = item.getId() + ".permission";
config.setDefaultValue(path, "none"); config.setDefaultValue(path, "none");
config.setDefaultValue(item.getID() + ".lore", new String[] { "&rYou do not have the permission", "&rto access this item." }); config.setDefaultValue(item.getId() + ".lore", new String[] { "&rYou do not have the permission", "&rto access this item." });
permissions.put(item.getID(), config.getString(path)); permissions.put(item.getId(), config.getString(path));
} }
} }
@ -72,7 +72,7 @@ public class PermissionsService {
return true; return true;
} }
String permission = permissions.get(item.getID()); String permission = permissions.get(item.getId());
return permission == null || permission.equals("none") || p.hasPermission(permission); return permission == null || permission.equals("none") || p.hasPermission(permission);
} }
@ -89,7 +89,7 @@ public class PermissionsService {
@Nonnull @Nonnull
public Optional<String> getPermission(@Nonnull SlimefunItem item) { public Optional<String> getPermission(@Nonnull SlimefunItem item) {
Validate.notNull(item, "Cannot get permissions for null"); Validate.notNull(item, "Cannot get permissions for null");
String permission = permissions.get(item.getID()); String permission = permissions.get(item.getId());
if (permission == null || permission.equals("none")) { if (permission == null || permission.equals("none")) {
return Optional.empty(); return Optional.empty();
@ -108,7 +108,7 @@ public class PermissionsService {
*/ */
public void setPermission(@Nonnull SlimefunItem item, @Nullable String permission) { public void setPermission(@Nonnull SlimefunItem item, @Nullable String permission) {
Validate.notNull(item, "You cannot set the permission for null"); Validate.notNull(item, "You cannot set the permission for null");
permissions.put(item.getID(), permission != null ? permission : "none"); permissions.put(item.getId(), permission != null ? permission : "none");
} }
/** /**
@ -124,7 +124,7 @@ public class PermissionsService {
@Nonnull @Nonnull
public List<String> getLore(@Nonnull SlimefunItem item) { public List<String> getLore(@Nonnull SlimefunItem item) {
List<String> lore = config.getStringList(item.getID() + ".lore"); List<String> lore = config.getStringList(item.getId() + ".lore");
return lore == null ? Arrays.asList("LORE NOT FOUND") : lore; return lore == null ? Arrays.asList("LORE NOT FOUND") : lore;
} }

View File

@ -7,8 +7,8 @@ import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataHolder; import org.bukkit.persistence.PersistentDataHolder;
import org.bukkit.persistence.PersistentDataType; import org.bukkit.persistence.PersistentDataType;
import io.github.thebusybiscuit.cscorelib2.data.PersistentDataAPI;
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion; import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
/** /**
* This interface is used to defer calls to Persistent Data and make sure they are only called * This interface is used to defer calls to Persistent Data and make sure they are only called
@ -16,23 +16,20 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
* *
* @author TheBusyBiscuit * @author TheBusyBiscuit
* *
* @deprecated This is redundant, we can use {@link PersistentDataAPI} instead.
*
*/ */
@Deprecated
interface PersistentDataService { interface PersistentDataService {
default void setString(Object obj, NamespacedKey key, String value) { default void setString(Object obj, NamespacedKey key, String value) {
if (SlimefunPlugin.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_14) && obj instanceof PersistentDataHolder) { PersistentDataContainer container = ((PersistentDataHolder) obj).getPersistentDataContainer();
PersistentDataContainer container = ((PersistentDataHolder) obj).getPersistentDataContainer(); container.set(key, PersistentDataType.STRING, value);
container.set(key, PersistentDataType.STRING, value);
}
} }
default Optional<String> getString(Object obj, NamespacedKey key) { default Optional<String> getString(Object obj, NamespacedKey key) {
if (SlimefunPlugin.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_14) && obj instanceof PersistentDataHolder) { PersistentDataContainer container = ((PersistentDataHolder) obj).getPersistentDataContainer();
PersistentDataContainer container = ((PersistentDataHolder) obj).getPersistentDataContainer(); return Optional.ofNullable(container.get(key, PersistentDataType.STRING));
return Optional.ofNullable(container.get(key, PersistentDataType.STRING));
}
return Optional.empty();
} }
} }

View File

@ -94,7 +94,7 @@ abstract class GitHubConnector {
} }
} catch (UnirestException e) { } catch (UnirestException e) {
if (github.isLoggingEnabled()) { if (github.isLoggingEnabled()) {
Slimefun.getLogger().log(Level.WARNING, "Could not connect to GitHub in time."); Slimefun.getLogger().log(Level.WARNING, "Could not connect to GitHub in time.", e);
} }
// It has the cached file, let's just read that then // It has the cached file, let's just read that then

View File

@ -88,7 +88,7 @@ class GitHubTask implements Runnable {
} catch (IOException x) { } catch (IOException x) {
// Too many requests // Too many requests
Slimefun.getLogger().log(Level.WARNING, "Attempted to connect to mojang.com, got this response: {0}: {1}", new Object[] { x.getClass().getSimpleName(), x.getMessage() }); Slimefun.getLogger().log(Level.WARNING, "Attempted to connect to mojang.com, got this response: {0}: {1}", new Object[] { x.getClass().getSimpleName(), x.getMessage() });
Slimefun.getLogger().log(Level.WARNING, "This usually means mojang.com is down or started to rate-limit this connection, this is not an error message!"); Slimefun.getLogger().log(Level.WARNING, "This usually means mojang.com is temporarily down or started to rate-limit this connection, this is not an error message!");
// Retry after 5 minutes if it was rate-limiting // Retry after 5 minutes if it was rate-limiting
if (x.getMessage().contains("429")) { if (x.getMessage().contains("429")) {

View File

@ -85,7 +85,7 @@ public abstract class SlimefunLocalization extends Localization implements Keyed
protected abstract void addLanguage(@Nonnull String id, @Nonnull String texture); protected abstract void addLanguage(@Nonnull String id, @Nonnull String texture);
protected void loadEmbeddedLanguages() { protected void loadEmbeddedLanguages() {
for (SupportedLanguage lang : SupportedLanguage.values) { for (SupportedLanguage lang : SupportedLanguage.valuesCache) {
if (lang.isReadyForRelease() || SlimefunPlugin.getUpdater().getBranch() != SlimefunBranch.STABLE) { if (lang.isReadyForRelease() || SlimefunPlugin.getUpdater().getBranch() != SlimefunBranch.STABLE) {
addLanguage(lang.getLanguageId(), lang.getTexture()); addLanguage(lang.getLanguageId(), lang.getTexture());
} }

View File

@ -58,7 +58,7 @@ enum SupportedLanguage {
MACEDONIAN("mk", false, "a0e0b0b5d87a855466980a101a757bcdb5f77d9f7287889f3efa998ee0472fc0"), MACEDONIAN("mk", false, "a0e0b0b5d87a855466980a101a757bcdb5f77d9f7287889f3efa998ee0472fc0"),
TAGALOG("tl", true, "9306c0c1ce6a9c61bb42a572c49e6d0ed20e0e6b3d122cc64c339cbf78e9e937"); TAGALOG("tl", true, "9306c0c1ce6a9c61bb42a572c49e6d0ed20e0e6b3d122cc64c339cbf78e9e937");
public static final SupportedLanguage[] values = values(); public static final SupportedLanguage[] valuesCache = values();
private final String id; private final String id;
private final boolean releaseReady; private final boolean releaseReady;

View File

@ -99,6 +99,9 @@ public class Translators {
addTranslator("Dr4gonD", "DragonD", SupportedLanguage.DUTCH, true); addTranslator("Dr4gonD", "DragonD", SupportedLanguage.DUTCH, true);
addTranslator("svr333", SupportedLanguage.DUTCH, false); addTranslator("svr333", SupportedLanguage.DUTCH, false);
addTranslator("PabloMarcendo", SupportedLanguage.DUTCH, true); addTranslator("PabloMarcendo", SupportedLanguage.DUTCH, true);
addTranslator("milvantiou", SupportedLanguage.DUTCH, true);
addTranslator("Sven313D", SupportedLanguage.DUTCH, true);
addTranslator("TypischTeun", SupportedLanguage.DUTCH, true);
// Translators - Danish // Translators - Danish
addTranslator("Mini-kun", SupportedLanguage.DANISH, true); addTranslator("Mini-kun", SupportedLanguage.DANISH, true);

View File

@ -11,11 +11,19 @@ import org.bukkit.event.Listener;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils; import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
import me.minebuilders.clearlag.Clearlag;
import me.minebuilders.clearlag.events.EntityRemoveEvent; import me.minebuilders.clearlag.events.EntityRemoveEvent;
class ClearLagHook implements Listener { /**
* This handles all integrations with {@link Clearlag}.
* We don't want it to clear our altar items.
*
* @author TheBusyBiscuit
*
*/
class ClearLagIntegration implements Listener {
ClearLagHook(@Nonnull SlimefunPlugin plugin) { ClearLagIntegration(@Nonnull SlimefunPlugin plugin) {
plugin.getServer().getPluginManager().registerEvents(this, plugin); plugin.getServer().getPluginManager().registerEvents(this, plugin);
} }

View File

@ -12,6 +12,7 @@ import io.github.thebusybiscuit.slimefun4.core.categories.FlexCategory;
import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideLayout; import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideLayout;
import me.mrCookieSlime.EmeraldEnchants.EnchantmentGuide; import me.mrCookieSlime.EmeraldEnchants.EnchantmentGuide;
@Deprecated
class EmeraldEnchantsCategory extends FlexCategory { class EmeraldEnchantsCategory extends FlexCategory {
public EmeraldEnchantsCategory(@Nonnull NamespacedKey key) { public EmeraldEnchantsCategory(@Nonnull NamespacedKey key) {

View File

@ -0,0 +1,60 @@
package io.github.thebusybiscuit.slimefun4.core.services.plugins;
import javax.annotation.Nonnull;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.inventory.ItemStack;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.events.skills.salvage.McMMOPlayerSalvageCheckEvent;
import io.github.thebusybiscuit.slimefun4.api.events.BlockPlacerPlaceEvent;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.items.VanillaItem;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
/**
* This handles all integrations with {@link mcMMO}.
*
* @author TheBusyBiscuit
*
*/
class McMMOIntegration implements Listener {
McMMOIntegration(@Nonnull SlimefunPlugin plugin) {
plugin.getServer().getPluginManager().registerEvents(this, plugin);
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onBlockPlacerPlace(BlockPlacerPlaceEvent e) {
// This registers blocks placed by the BlockPlacer as "player-placed"
mcMMO.getPlaceStore().setTrue(e.getBlock());
}
@EventHandler(ignoreCancelled = true)
public void onItemSalvage(McMMOPlayerSalvageCheckEvent e) {
// Prevent Slimefun items from being salvaged
if (!isSalvageable(e.getSalvageItem())) {
e.setCancelled(true);
SlimefunPlugin.getLocalization().sendMessage(e.getPlayer(), "anvil.mcmmo-salvaging");
}
}
/**
* This method checks if an {@link ItemStack} can be salvaged or not.
* We basically don't want players to salvage any {@link SlimefunItem} unless
* it is a {@link VanillaItem}.
*
* @param item
* The {@link ItemStack} to check
*
* @return Whether this item can be safely salvaged
*/
private boolean isSalvageable(@Nonnull ItemStack item) {
SlimefunItem sfItem = SlimefunItem.getByItem(item);
return sfItem == null || sfItem instanceof VanillaItem;
}
}

View File

@ -13,14 +13,21 @@ import org.bukkit.entity.Player;
import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile; import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile;
import io.github.thebusybiscuit.slimefun4.core.researching.Research; import io.github.thebusybiscuit.slimefun4.core.researching.Research;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import me.clip.placeholderapi.PlaceholderAPI;
import me.clip.placeholderapi.expansion.PlaceholderExpansion; import me.clip.placeholderapi.expansion.PlaceholderExpansion;
class PlaceholderAPIHook extends PlaceholderExpansion { /**
* This is our integration for {@link PlaceholderAPI}.
*
* @author TheBusyBiscuit
*
*/
class PlaceholderAPIIntegration extends PlaceholderExpansion {
private final String version; private final String version;
private final String author; private final String author;
public PlaceholderAPIHook(@Nonnull SlimefunPlugin plugin) { public PlaceholderAPIIntegration(@Nonnull SlimefunPlugin plugin) {
this.version = plugin.getDescription().getVersion(); this.version = plugin.getDescription().getVersion();
this.author = plugin.getDescription().getAuthors().toString(); this.author = plugin.getDescription().getAuthors().toString();
} }

View File

@ -5,12 +5,16 @@ import java.util.function.Function;
import java.util.logging.Level; import java.util.logging.Level;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.ParametersAreNonnullByDefault;
import org.bukkit.NamespacedKey; import org.bukkit.NamespacedKey;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.event.Event;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
import com.gmail.nossr50.events.fake.FakeBlockBreakEvent;
import io.github.thebusybiscuit.slimefun4.api.SlimefunAddon; import io.github.thebusybiscuit.slimefun4.api.SlimefunAddon;
import io.github.thebusybiscuit.slimefun4.core.categories.FlexCategory; import io.github.thebusybiscuit.slimefun4.core.categories.FlexCategory;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
@ -31,25 +35,41 @@ public class ThirdPartyPluginService {
private final SlimefunPlugin plugin; private final SlimefunPlugin plugin;
private boolean initialized = false;
private boolean isExoticGardenInstalled = false; private boolean isExoticGardenInstalled = false;
private boolean isChestTerminalInstalled = false; private boolean isChestTerminalInstalled = false;
private boolean isEmeraldEnchantsInstalled = false; private boolean isEmeraldEnchantsInstalled = false;
private boolean isCoreProtectInstalled = false; private boolean isMcMMOInstalled = false;
private boolean isPlaceholderAPIInstalled = false;
// Overridden if ExoticGarden is loaded /**
* This gets overridden if ExoticGarden is loaded
*/
private Function<Block, Optional<ItemStack>> exoticGardenIntegration = b -> Optional.empty(); private Function<Block, Optional<ItemStack>> exoticGardenIntegration = b -> Optional.empty();
/**
* This initializes the {@link ThirdPartyPluginService}
*
* @param plugin
* Our instance of {@link SlimefunPlugin}
*/
public ThirdPartyPluginService(@Nonnull SlimefunPlugin plugin) { public ThirdPartyPluginService(@Nonnull SlimefunPlugin plugin) {
this.plugin = plugin; this.plugin = plugin;
} }
/**
* This method initializes all third party integrations.
*/
public void start() { public void start() {
if (initialized) {
throw new UnsupportedOperationException("Third Party Integrations have already been initialized!");
}
initialized = true;
if (isPluginInstalled("PlaceholderAPI")) { if (isPluginInstalled("PlaceholderAPI")) {
try { try {
PlaceholderAPIHook hook = new PlaceholderAPIHook(plugin); PlaceholderAPIIntegration hook = new PlaceholderAPIIntegration(plugin);
hook.register(); hook.register();
isPlaceholderAPIInstalled = true;
} catch (Exception | LinkageError x) { } catch (Exception | LinkageError x) {
String version = plugin.getServer().getPluginManager().getPlugin("PlaceholderAPI").getDescription().getVersion(); String version = plugin.getServer().getPluginManager().getPlugin("PlaceholderAPI").getDescription().getVersion();
@ -69,7 +89,7 @@ public class ThirdPartyPluginService {
if (isPluginInstalled("WorldEdit")) { if (isPluginInstalled("WorldEdit")) {
try { try {
Class.forName("com.sk89q.worldedit.extent.Extent"); Class.forName("com.sk89q.worldedit.extent.Extent");
new WorldEditHook(); new WorldEditIntegration();
} catch (Exception | LinkageError x) { } catch (Exception | LinkageError x) {
String version = plugin.getServer().getPluginManager().getPlugin("WorldEdit").getDescription().getVersion(); String version = plugin.getServer().getPluginManager().getPlugin("WorldEdit").getDescription().getVersion();
@ -78,6 +98,21 @@ public class ThirdPartyPluginService {
} }
} }
// mcMMO Integration
if (isPluginInstalled("mcMMO")) {
try {
// This makes sure that the FakeEvent interface is present.
// Class.forName("com.gmail.nossr50.events.fake.FakeEvent");
new McMMOIntegration(plugin);
isMcMMOInstalled = true;
} catch (Exception | LinkageError x) {
String version = plugin.getServer().getPluginManager().getPlugin("mcMMO").getDescription().getVersion();
Slimefun.getLogger().log(Level.WARNING, "Maybe consider updating mcMMO or Slimefun?");
Slimefun.getLogger().log(Level.WARNING, x, () -> "Failed to hook into mcMMO v" + version);
}
}
/* /*
* These Items are not marked as soft-dependencies and * These Items are not marked as soft-dependencies and
* therefore need to be loaded after the Server has finished * therefore need to be loaded after the Server has finished
@ -85,7 +120,7 @@ public class ThirdPartyPluginService {
*/ */
plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, () -> { plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, () -> {
if (isPluginInstalled("ClearLag")) { if (isPluginInstalled("ClearLag")) {
new ClearLagHook(plugin); new ClearLagIntegration(plugin);
} }
isChestTerminalInstalled = isPluginInstalled("ChestTerminal"); isChestTerminalInstalled = isPluginInstalled("ChestTerminal");
@ -101,6 +136,7 @@ public class ThirdPartyPluginService {
} }
} }
@ParametersAreNonnullByDefault
public void loadExoticGarden(Plugin plugin, Function<Block, Optional<ItemStack>> method) { public void loadExoticGarden(Plugin plugin, Function<Block, Optional<ItemStack>> method) {
if (plugin.getName().equals("ExoticGarden")) { if (plugin.getName().equals("ExoticGarden")) {
isExoticGardenInstalled = true; isExoticGardenInstalled = true;
@ -120,16 +156,22 @@ public class ThirdPartyPluginService {
return isEmeraldEnchantsInstalled; return isEmeraldEnchantsInstalled;
} }
public boolean isCoreProtectInstalled() {
return isCoreProtectInstalled;
}
public boolean isPlaceholderAPIInstalled() {
return isPlaceholderAPIInstalled;
}
public Optional<ItemStack> harvestExoticGardenPlant(Block block) { public Optional<ItemStack> harvestExoticGardenPlant(Block block) {
return exoticGardenIntegration.apply(block); return exoticGardenIntegration.apply(block);
} }
/**
* This checks if one of our third party integrations faked an {@link Event}.
* Faked {@link Event Events} should be ignored in our logic.
*
* @param event
* The {@link Event} to test
*
* @return Whether this is a fake event
*/
public boolean isEventFaked(@Nonnull Event event) {
// TODO: Change this to FakeEvent once the new mcMMO build was released
return isMcMMOInstalled && event instanceof FakeBlockBreakEvent;
}
} }

View File

@ -14,9 +14,16 @@ import com.sk89q.worldedit.world.block.BlockStateHolder;
import me.mrCookieSlime.Slimefun.api.BlockStorage; import me.mrCookieSlime.Slimefun.api.BlockStorage;
class WorldEditHook { /**
* This handles all integrations with {@link WorldEdit}.
* If an are is cleared, we also wanna clear all Slimefun-related block data.
*
* @author TheBusyBiscuit
*
*/
class WorldEditIntegration {
WorldEditHook() { WorldEditIntegration() {
WorldEdit.getInstance().getEventBus().register(this); WorldEdit.getInstance().getEventBus().register(this);
} }

View File

@ -31,7 +31,7 @@ public enum PerformanceRating implements Predicate<Float> {
HURTFUL(ChatColor.DARK_RED, 500), HURTFUL(ChatColor.DARK_RED, 500),
BAD(ChatColor.DARK_RED, Float.MAX_VALUE); BAD(ChatColor.DARK_RED, Float.MAX_VALUE);
public static final PerformanceRating[] values = values(); public static final PerformanceRating[] valuesCache = values();
private final ChatColor color; private final ChatColor color;
private final float threshold; private final float threshold;

View File

@ -46,7 +46,7 @@ class ProfiledBlock {
} }
public String getId() { public String getId() {
return item.getID(); return item.getId();
} }
public SlimefunAddon getAddon() { public SlimefunAddon getAddon() {

View File

@ -296,7 +296,7 @@ public class SlimefunProfiler {
public PerformanceRating getPerformance() { public PerformanceRating getPerformance() {
float percentage = getPercentageOfTick(); float percentage = getPercentageOfTick();
for (PerformanceRating rating : PerformanceRating.values) { for (PerformanceRating rating : PerformanceRating.valuesCache) {
if (rating.test(percentage)) { if (rating.test(percentage)) {
return rating; return rating;
} }
@ -344,7 +344,7 @@ public class SlimefunProfiler {
public String getTime(@Nonnull SlimefunItem item) { public String getTime(@Nonnull SlimefunItem item) {
Validate.notNull("Cannot get timings for a null SlimefunItem"); Validate.notNull("Cannot get timings for a null SlimefunItem");
long time = getByItem().getOrDefault(item.getID(), 0L); long time = getByItem().getOrDefault(item.getId(), 0L);
return NumberUtils.getAsMillis(time); return NumberUtils.getAsMillis(time);
} }

View File

@ -581,14 +581,14 @@ public final class SlimefunItems {
public static final SlimefunItemStack ENHANCED_CRAFTING_TABLE = new SlimefunItemStack("ENHANCED_CRAFTING_TABLE", Material.CRAFTING_TABLE, "&eEnhanced Crafting Table", "", "&aA regular Crafting Table cannot", "&ahold this massive Amount of Power..."); public static final SlimefunItemStack ENHANCED_CRAFTING_TABLE = new SlimefunItemStack("ENHANCED_CRAFTING_TABLE", Material.CRAFTING_TABLE, "&eEnhanced Crafting Table", "", "&aA regular Crafting Table cannot", "&ahold this massive Amount of Power...");
public static final SlimefunItemStack GRIND_STONE = new SlimefunItemStack("GRIND_STONE", Material.DISPENSER, "&bGrind Stone", "", "&aGrinds items down into other items"); public static final SlimefunItemStack GRIND_STONE = new SlimefunItemStack("GRIND_STONE", Material.DISPENSER, "&bGrind Stone", "", "&aGrinds items down into other items");
public static final SlimefunItemStack ARMOR_FORGE = new SlimefunItemStack("ARMOR_FORGE", Material.ANVIL, "&6Armor Forge", "", "&aGives you the ability to create powerful armor"); public static final SlimefunItemStack ARMOR_FORGE = new SlimefunItemStack("ARMOR_FORGE", Material.ANVIL, "&6Armor Forge", "", "&aGives you the ability to create powerful armor");
public static final SlimefunItemStack MAKESHIFT_SMELTERY; public static final SlimefunItemStack MAKESHIFT_SMELTERY = new SlimefunItemStack("MAKESHIFT_SMELTERY", Material.BLAST_FURNACE, "&eMakeshift Smeltery", "", "&fImprovised version of the Smeltery", "&fthat only allows you to", "&fsmelt dusts into ingots");
public static final SlimefunItemStack SMELTERY = new SlimefunItemStack("SMELTERY", Material.FURNACE, "&6Smeltery", "", "&fA high-temperature furnace", "&fthat allows you to smelt dusts", "&finto ingots and create alloys."); public static final SlimefunItemStack SMELTERY = new SlimefunItemStack("SMELTERY", Material.FURNACE, "&6Smeltery", "", "&fA high-temperature furnace", "&fthat allows you to smelt dusts", "&finto ingots and create alloys.");
public static final SlimefunItemStack ORE_CRUSHER = new SlimefunItemStack("ORE_CRUSHER", Material.DISPENSER, "&bOre Crusher", "", "&aCrushes ores to double them"); public static final SlimefunItemStack ORE_CRUSHER = new SlimefunItemStack("ORE_CRUSHER", Material.DISPENSER, "&bOre Crusher", "", "&aCrushes ores to double them");
public static final SlimefunItemStack COMPRESSOR = new SlimefunItemStack("COMPRESSOR", Material.PISTON, "&bCompressor", "", "&aCompresses Items"); public static final SlimefunItemStack COMPRESSOR = new SlimefunItemStack("COMPRESSOR", Material.PISTON, "&bCompressor", "", "&aCompresses Items");
public static final SlimefunItemStack PRESSURE_CHAMBER = new SlimefunItemStack("PRESSURE_CHAMBER", Material.GLASS, "&bPressure Chamber", "", "&aCompresses Items even further"); public static final SlimefunItemStack PRESSURE_CHAMBER = new SlimefunItemStack("PRESSURE_CHAMBER", Material.GLASS, "&bPressure Chamber", "", "&aCompresses Items even further");
public static final SlimefunItemStack MAGIC_WORKBENCH = new SlimefunItemStack("MAGIC_WORKBENCH", Material.CRAFTING_TABLE, "&6Magic Workbench", "", "&dInfuses Items with magical Energy"); public static final SlimefunItemStack MAGIC_WORKBENCH = new SlimefunItemStack("MAGIC_WORKBENCH", Material.CRAFTING_TABLE, "&6Magic Workbench", "", "&dInfuses Items with magical Energy");
public static final SlimefunItemStack ORE_WASHER = new SlimefunItemStack("ORE_WASHER", Material.CAULDRON, "&6Ore Washer", "", "&aWashes Sifted Ore to filter Ores", "&aand gives you small Stone Chunks"); public static final SlimefunItemStack ORE_WASHER = new SlimefunItemStack("ORE_WASHER", Material.CAULDRON, "&6Ore Washer", "", "&aWashes Sifted Ore to filter Ores", "&aand gives you small Stone Chunks");
public static final SlimefunItemStack TABLE_SAW; public static final SlimefunItemStack TABLE_SAW = new SlimefunItemStack("TABLE_SAW", Material.STONECUTTER, "&6Table Saw", "", "&aAllows you to get 8 planks from 1 Log", "&a(Works with all log types)");
public static final SlimefunItemStack JUICER = new SlimefunItemStack("JUICER", Material.GLASS_BOTTLE, "&aJuicer", "", "&aAllows you to create delicious Juice"); public static final SlimefunItemStack JUICER = new SlimefunItemStack("JUICER", Material.GLASS_BOTTLE, "&aJuicer", "", "&aAllows you to create delicious Juice");
public static final SlimefunItemStack AUTOMATED_PANNING_MACHINE = new SlimefunItemStack("AUTOMATED_PANNING_MACHINE", Material.BOWL, "&eAutomated Panning Machine", "", "&fA MultiBlock Version of the Gold Pan", "&fand Nether Gold Pan combined in one machine."); public static final SlimefunItemStack AUTOMATED_PANNING_MACHINE = new SlimefunItemStack("AUTOMATED_PANNING_MACHINE", Material.BOWL, "&eAutomated Panning Machine", "", "&fA MultiBlock Version of the Gold Pan", "&fand Nether Gold Pan combined in one machine.");
@ -676,22 +676,22 @@ public final class SlimefunItems {
public static final SlimefunItemStack ELECTRIC_ORE_GRINDER = new SlimefunItemStack("ELECTRIC_ORE_GRINDER", Material.FURNACE, "&cElectric Ore Grinder", "", "&fWorks as an Ore Crusher and Grind Stone", "", LoreBuilder.machine(MachineTier.ADVANCED, MachineType.MACHINE), LoreBuilder.speed(1), LoreBuilder.powerPerSecond(12)); public static final SlimefunItemStack ELECTRIC_ORE_GRINDER = new SlimefunItemStack("ELECTRIC_ORE_GRINDER", Material.FURNACE, "&cElectric Ore Grinder", "", "&fWorks as an Ore Crusher and Grind Stone", "", LoreBuilder.machine(MachineTier.ADVANCED, MachineType.MACHINE), LoreBuilder.speed(1), LoreBuilder.powerPerSecond(12));
public static final SlimefunItemStack ELECTRIC_ORE_GRINDER_2 = new SlimefunItemStack("ELECTRIC_ORE_GRINDER_2", Material.FURNACE, "&cElectric Ore Grinder &7(&eII&7)", "", "&fWorks as an Ore Crusher and Grind Stone", "", LoreBuilder.machine(MachineTier.END_GAME, MachineType.MACHINE), LoreBuilder.speed(4), LoreBuilder.powerPerSecond(30)); public static final SlimefunItemStack ELECTRIC_ORE_GRINDER_2 = new SlimefunItemStack("ELECTRIC_ORE_GRINDER_2", Material.FURNACE, "&cElectric Ore Grinder &7(&eII&7)", "", "&fWorks as an Ore Crusher and Grind Stone", "", LoreBuilder.machine(MachineTier.END_GAME, MachineType.MACHINE), LoreBuilder.speed(4), LoreBuilder.powerPerSecond(30));
public static final SlimefunItemStack ELECTRIC_INGOT_PULVERIZER = new SlimefunItemStack("ELECTRIC_INGOT_PULVERIZER", Material.FURNACE, "&cElectric Ingot Pulverizer", "", "&fPulverizes Ingots into Dust", "", LoreBuilder.machine(MachineTier.MEDIUM, MachineType.MACHINE), LoreBuilder.speed(1), LoreBuilder.powerPerSecond(14)); public static final SlimefunItemStack ELECTRIC_INGOT_PULVERIZER = new SlimefunItemStack("ELECTRIC_INGOT_PULVERIZER", Material.FURNACE, "&cElectric Ingot Pulverizer", "", "&fPulverizes Ingots into Dust", "", LoreBuilder.machine(MachineTier.MEDIUM, MachineType.MACHINE), LoreBuilder.speed(1), LoreBuilder.powerPerSecond(14));
public static final SlimefunItemStack AUTO_DRIER; public static final SlimefunItemStack AUTO_DRIER = new SlimefunItemStack("AUTO_DRIER", Material.SMOKER, "&6Auto Drier", "", LoreBuilder.machine(MachineTier.MEDIUM, MachineType.MACHINE), LoreBuilder.speed(1), LoreBuilder.powerPerSecond(10));
public static final SlimefunItemStack AUTO_ENCHANTER = new SlimefunItemStack("AUTO_ENCHANTER", Material.ENCHANTING_TABLE, "&5Auto Enchanter", "", LoreBuilder.machine(MachineTier.MEDIUM, MachineType.MACHINE), LoreBuilder.speed(1), LoreBuilder.powerPerSecond(18)); public static final SlimefunItemStack AUTO_ENCHANTER = new SlimefunItemStack("AUTO_ENCHANTER", Material.ENCHANTING_TABLE, "&5Auto Enchanter", "", LoreBuilder.machine(MachineTier.MEDIUM, MachineType.MACHINE), LoreBuilder.speed(1), LoreBuilder.powerPerSecond(18));
public static final SlimefunItemStack AUTO_DISENCHANTER = new SlimefunItemStack("AUTO_DISENCHANTER", Material.ENCHANTING_TABLE, "&5Auto Disenchanter", "", LoreBuilder.machine(MachineTier.MEDIUM, MachineType.MACHINE), LoreBuilder.speed(1), LoreBuilder.powerPerSecond(18)); public static final SlimefunItemStack AUTO_DISENCHANTER = new SlimefunItemStack("AUTO_DISENCHANTER", Material.ENCHANTING_TABLE, "&5Auto Disenchanter", "", LoreBuilder.machine(MachineTier.MEDIUM, MachineType.MACHINE), LoreBuilder.speed(1), LoreBuilder.powerPerSecond(18));
public static final SlimefunItemStack AUTO_ANVIL = new SlimefunItemStack("AUTO_ANVIL", Material.IRON_BLOCK, "&7Auto Anvil", "", LoreBuilder.machine(MachineTier.ADVANCED, MachineType.MACHINE), "&8\u21E8 &7Repair Factor: 10%", LoreBuilder.powerPerSecond(24)); public static final SlimefunItemStack AUTO_ANVIL = new SlimefunItemStack("AUTO_ANVIL", Material.IRON_BLOCK, "&7Auto Anvil", "", LoreBuilder.machine(MachineTier.ADVANCED, MachineType.MACHINE), "&8\u21E8 &7Repair Factor: 10%", LoreBuilder.powerPerSecond(24));
public static final SlimefunItemStack AUTO_ANVIL_2 = new SlimefunItemStack("AUTO_ANVIL_2", Material.IRON_BLOCK, "&7Auto Anvil Mk.II", "", LoreBuilder.machine(MachineTier.END_GAME, MachineType.MACHINE), "&8\u21E8 &7Repair Factor: 25%", LoreBuilder.powerPerSecond(32)); public static final SlimefunItemStack AUTO_ANVIL_2 = new SlimefunItemStack("AUTO_ANVIL_2", Material.IRON_BLOCK, "&7Auto Anvil Mk.II", "", LoreBuilder.machine(MachineTier.END_GAME, MachineType.MACHINE), "&8\u21E8 &7Repair Factor: 25%", LoreBuilder.powerPerSecond(32));
public static final SlimefunItemStack AUTO_BREWER; public static final SlimefunItemStack AUTO_BREWER = new SlimefunItemStack("AUTO_BREWER", Material.SMOKER, "&6Auto Brewer", "", LoreBuilder.machine(MachineTier.MEDIUM, MachineType.MACHINE), LoreBuilder.speed(1), LoreBuilder.powerPerSecond(12));
public static final SlimefunItemStack BIO_REACTOR = new SlimefunItemStack("BIO_REACTOR", Material.LIME_TERRACOTTA, "&2Bio Reactor", "", LoreBuilder.machine(MachineTier.AVERAGE, MachineType.GENERATOR), LoreBuilder.powerBuffer(128), LoreBuilder.powerPerSecond(8)); public static final SlimefunItemStack BIO_REACTOR = new SlimefunItemStack("BIO_REACTOR", Material.LIME_TERRACOTTA, "&2Bio Reactor", "", LoreBuilder.machine(MachineTier.AVERAGE, MachineType.GENERATOR), LoreBuilder.powerBuffer(128), LoreBuilder.powerPerSecond(8));
public static final SlimefunItemStack MULTIMETER = new SlimefunItemStack("MULTIMETER", Material.CLOCK, "&eMultimeter", "", "&fMeasures the Amount of stored", "&fEnergy in a Block"); public static final SlimefunItemStack MULTIMETER = new SlimefunItemStack("MULTIMETER", Material.CLOCK, "&eMultimeter", "", "&fMeasures the Amount of stored", "&fEnergy in a Block");
public static final SlimefunItemStack SMALL_CAPACITOR = new SlimefunItemStack("SMALL_CAPACITOR", HeadTexture.CAPACITOR_25, "&aSmall Energy Capacitor", "", LoreBuilder.machine(MachineTier.BASIC, MachineType.CAPACITOR), "&8\u21E8 &e\u26A1 &7128 J Capacity"); public static final SlimefunItemStack SMALL_CAPACITOR = new SlimefunItemStack("SMALL_CAPACITOR", HeadTexture.CAPACITOR_25, "&aSmall Energy Capacitor", LoreBuilder.range(6), "", LoreBuilder.machine(MachineTier.BASIC, MachineType.CAPACITOR), "&8\u21E8 &e\u26A1 &7128 J Capacity");
public static final SlimefunItemStack MEDIUM_CAPACITOR = new SlimefunItemStack("MEDIUM_CAPACITOR", HeadTexture.CAPACITOR_25, "&aMedium Energy Capacitor", "", LoreBuilder.machine(MachineTier.AVERAGE, MachineType.CAPACITOR), "&8\u21E8 &e\u26A1 &7512 J Capacity"); public static final SlimefunItemStack MEDIUM_CAPACITOR = new SlimefunItemStack("MEDIUM_CAPACITOR", HeadTexture.CAPACITOR_25, "&aMedium Energy Capacitor", LoreBuilder.range(6), "", LoreBuilder.machine(MachineTier.AVERAGE, MachineType.CAPACITOR), "&8\u21E8 &e\u26A1 &7512 J Capacity");
public static final SlimefunItemStack BIG_CAPACITOR = new SlimefunItemStack("BIG_CAPACITOR", HeadTexture.CAPACITOR_25, "&aBig Energy Capacitor", "", LoreBuilder.machine(MachineTier.MEDIUM, MachineType.CAPACITOR), "&8\u21E8 &e\u26A1 &71024 J Capacity"); public static final SlimefunItemStack BIG_CAPACITOR = new SlimefunItemStack("BIG_CAPACITOR", HeadTexture.CAPACITOR_25, "&aBig Energy Capacitor", LoreBuilder.range(6), "", LoreBuilder.machine(MachineTier.MEDIUM, MachineType.CAPACITOR), "&8\u21E8 &e\u26A1 &71024 J Capacity");
public static final SlimefunItemStack LARGE_CAPACITOR = new SlimefunItemStack("LARGE_CAPACITOR", HeadTexture.CAPACITOR_25, "&aLarge Energy Capacitor", "", LoreBuilder.machine(MachineTier.GOOD, MachineType.CAPACITOR), "&8\u21E8 &e\u26A1 &78192 J Capacity"); public static final SlimefunItemStack LARGE_CAPACITOR = new SlimefunItemStack("LARGE_CAPACITOR", HeadTexture.CAPACITOR_25, "&aLarge Energy Capacitor", LoreBuilder.range(6), "", LoreBuilder.machine(MachineTier.GOOD, MachineType.CAPACITOR), "&8\u21E8 &e\u26A1 &78192 J Capacity");
public static final SlimefunItemStack CARBONADO_EDGED_CAPACITOR = new SlimefunItemStack("CARBONADO_EDGED_CAPACITOR", HeadTexture.CAPACITOR_25, "&aCarbonado Edged Energy Capacitor", "", LoreBuilder.machine(MachineTier.END_GAME, MachineType.CAPACITOR), "&8\u21E8 &e\u26A1 &765536 J Capacity"); public static final SlimefunItemStack CARBONADO_EDGED_CAPACITOR = new SlimefunItemStack("CARBONADO_EDGED_CAPACITOR", HeadTexture.CAPACITOR_25, "&aCarbonado Edged Energy Capacitor", LoreBuilder.range(6), "", LoreBuilder.machine(MachineTier.END_GAME, MachineType.CAPACITOR), "&8\u21E8 &e\u26A1 &765536 J Capacity");
public static final SlimefunItemStack ENERGIZED_CAPACITOR = new SlimefunItemStack("ENERGIZED_CAPACITOR", HeadTexture.CAPACITOR_25, "&aEnergized Energy Capacitor", "", LoreBuilder.machine(MachineTier.END_GAME, MachineType.CAPACITOR), "&8\u21E8 &e\u26A1 &7524288 J Capacity"); public static final SlimefunItemStack ENERGIZED_CAPACITOR = new SlimefunItemStack("ENERGIZED_CAPACITOR", HeadTexture.CAPACITOR_25, "&aEnergized Energy Capacitor", LoreBuilder.range(6), "", LoreBuilder.machine(MachineTier.END_GAME, MachineType.CAPACITOR), "&8\u21E8 &e\u26A1 &7524288 J Capacity");
/* Robots */ /* Robots */
public static final SlimefunItemStack PROGRAMMABLE_ANDROID = new SlimefunItemStack("PROGRAMMABLE_ANDROID", HeadTexture.PROGRAMMABLE_ANDROID, "&cProgrammable Android &7(Normal)", "", "&8\u21E8 &7Function: None", "&8\u21E8 &7Fuel Efficiency: 1.0x"); public static final SlimefunItemStack PROGRAMMABLE_ANDROID = new SlimefunItemStack("PROGRAMMABLE_ANDROID", HeadTexture.PROGRAMMABLE_ANDROID, "&cProgrammable Android &7(Normal)", "", "&8\u21E8 &7Function: None", "&8\u21E8 &7Fuel Efficiency: 1.0x");
@ -764,6 +764,7 @@ public final class SlimefunItems {
public static final SlimefunItemStack BLISTERING_INGOT_3 = new SlimefunItemStack("BLISTERING_INGOT_3", Material.GOLD_INGOT, "&6Blistering Ingot", "", LoreBuilder.radioactive(Radioactivity.VERY_HIGH), LoreBuilder.HAZMAT_SUIT_REQUIRED); public static final SlimefunItemStack BLISTERING_INGOT_3 = new SlimefunItemStack("BLISTERING_INGOT_3", Material.GOLD_INGOT, "&6Blistering Ingot", "", LoreBuilder.radioactive(Radioactivity.VERY_HIGH), LoreBuilder.HAZMAT_SUIT_REQUIRED);
public static final SlimefunItemStack ENERGY_REGULATOR = new SlimefunItemStack("ENERGY_REGULATOR", HeadTexture.ENERGY_REGULATOR, "&6Energy Regulator", "", "&fCore Component of an Energy Network"); public static final SlimefunItemStack ENERGY_REGULATOR = new SlimefunItemStack("ENERGY_REGULATOR", HeadTexture.ENERGY_REGULATOR, "&6Energy Regulator", "", "&fCore Component of an Energy Network");
public static final SlimefunItemStack ENERGY_CONNECTOR = new SlimefunItemStack("ENERGY_CONNECTOR", HeadTexture.ENERGY_CONNECTOR, "&eEnergy Connector", LoreBuilder.range(6), "", "&fPlace this between machines", "&fand generators to connect them", "&fto your regulator.");
public static final SlimefunItemStack DEBUG_FISH = new SlimefunItemStack("DEBUG_FISH", Material.SALMON, "&3How much is the Fish?", "", "&eRight Click &fany Block to view it's BlockData", "&eLeft Click &fto break a Block", "&eShift + Left Click &fany Block to erase it's BlockData", "&eShift + Right Click &fto place a Placeholder Block"); public static final SlimefunItemStack DEBUG_FISH = new SlimefunItemStack("DEBUG_FISH", Material.SALMON, "&3How much is the Fish?", "", "&eRight Click &fany Block to view it's BlockData", "&eLeft Click &fto break a Block", "&eShift + Left Click &fany Block to erase it's BlockData", "&eShift + Right Click &fto place a Placeholder Block");
public static final SlimefunItemStack NETHER_ICE = new SlimefunItemStack("NETHER_ICE", HeadTexture.NETHER_ICE, "&eNether Ice", "", LoreBuilder.radioactive(Radioactivity.MODERATE), LoreBuilder.HAZMAT_SUIT_REQUIRED); public static final SlimefunItemStack NETHER_ICE = new SlimefunItemStack("NETHER_ICE", HeadTexture.NETHER_ICE, "&eNether Ice", "", LoreBuilder.radioactive(Radioactivity.MODERATE), LoreBuilder.HAZMAT_SUIT_REQUIRED);
@ -854,17 +855,5 @@ public final class SlimefunItems {
static { static {
INFUSED_ELYTRA.addUnsafeEnchantment(Enchantment.MENDING, 1); INFUSED_ELYTRA.addUnsafeEnchantment(Enchantment.MENDING, 1);
if (SlimefunPlugin.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_14)) {
TABLE_SAW = new SlimefunItemStack("TABLE_SAW", Material.STONECUTTER, "&6Table Saw", "", "&aAllows you to get 8 planks from 1 Log", "&a(Works with all log types)");
MAKESHIFT_SMELTERY = new SlimefunItemStack("MAKESHIFT_SMELTERY", Material.BLAST_FURNACE, "&eMakeshift Smeltery", "", "&fImprovised version of the Smeltery", "&fthat only allows you to", "&fsmelt dusts into ingots");
AUTO_DRIER = new SlimefunItemStack("AUTO_DRIER", Material.SMOKER, "&6Auto Drier", "", LoreBuilder.machine(MachineTier.MEDIUM, MachineType.MACHINE), LoreBuilder.speed(1), LoreBuilder.powerPerSecond(10));
AUTO_BREWER = new SlimefunItemStack("AUTO_BREWER", Material.SMOKER, "&6Auto Brewer", "", LoreBuilder.machine(MachineTier.MEDIUM, MachineType.MACHINE), LoreBuilder.speed(1), LoreBuilder.powerPerSecond(12));
} else {
TABLE_SAW = null;
MAKESHIFT_SMELTERY = new SlimefunItemStack("MAKESHIFT_SMELTERY", Material.FURNACE, "&eMakeshift Smeltery", "", "&fImprovised version of the Smeltery", "&fthat only allows you to", "&fsmelt dusts into ingots");
AUTO_DRIER = new SlimefunItemStack("AUTO_DRIER", Material.FURNACE, "&6Auto Drier", "", LoreBuilder.machine(MachineTier.MEDIUM, MachineType.MACHINE), LoreBuilder.speed(1), LoreBuilder.powerPerSecond(10));
AUTO_BREWER = new SlimefunItemStack("AUTO_BREWER", Material.BREWING_STAND, "&6Auto Brewer", LoreBuilder.machine(MachineTier.MEDIUM, MachineType.MACHINE), LoreBuilder.speed(1), LoreBuilder.powerPerSecond(12));
}
} }
} }

View File

@ -30,6 +30,7 @@ import io.github.thebusybiscuit.cscorelib2.protection.ProtectionManager;
import io.github.thebusybiscuit.cscorelib2.reflection.ReflectionUtils; import io.github.thebusybiscuit.cscorelib2.reflection.ReflectionUtils;
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion; import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
import io.github.thebusybiscuit.slimefun4.api.SlimefunAddon; import io.github.thebusybiscuit.slimefun4.api.SlimefunAddon;
import io.github.thebusybiscuit.slimefun4.api.exceptions.TagMisconfigurationException;
import io.github.thebusybiscuit.slimefun4.api.gps.GPSNetwork; import io.github.thebusybiscuit.slimefun4.api.gps.GPSNetwork;
import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile; import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile;
import io.github.thebusybiscuit.slimefun4.core.SlimefunRegistry; import io.github.thebusybiscuit.slimefun4.core.SlimefunRegistry;
@ -89,10 +90,15 @@ import io.github.thebusybiscuit.slimefun4.implementation.listeners.SlimefunItemL
import io.github.thebusybiscuit.slimefun4.implementation.listeners.SoulboundListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.SoulboundListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.TalismanListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.TalismanListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.VampireBladeListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.VampireBladeListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.VanillaMachinesListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.VillagerTradingListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.VillagerTradingListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.WitherListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.WitherListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.WorldListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.WorldListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.crafting.AnvilListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.crafting.BrewingStandListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.crafting.CartographyTableListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.crafting.CauldronListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.crafting.CraftingTableListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.crafting.GrindstoneListener;
import io.github.thebusybiscuit.slimefun4.implementation.resources.GEOResourcesSetup; import io.github.thebusybiscuit.slimefun4.implementation.resources.GEOResourcesSetup;
import io.github.thebusybiscuit.slimefun4.implementation.setup.PostSetup; import io.github.thebusybiscuit.slimefun4.implementation.setup.PostSetup;
import io.github.thebusybiscuit.slimefun4.implementation.setup.ResearchSetup; import io.github.thebusybiscuit.slimefun4.implementation.setup.ResearchSetup;
@ -100,6 +106,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.setup.SlimefunItemSetup
import io.github.thebusybiscuit.slimefun4.implementation.tasks.ArmorTask; import io.github.thebusybiscuit.slimefun4.implementation.tasks.ArmorTask;
import io.github.thebusybiscuit.slimefun4.implementation.tasks.SlimefunStartupTask; import io.github.thebusybiscuit.slimefun4.implementation.tasks.SlimefunStartupTask;
import io.github.thebusybiscuit.slimefun4.implementation.tasks.TickerTask; import io.github.thebusybiscuit.slimefun4.implementation.tasks.TickerTask;
import io.github.thebusybiscuit.slimefun4.utils.tags.SlimefunTag;
import io.papermc.lib.PaperLib; import io.papermc.lib.PaperLib;
import me.mrCookieSlime.CSCoreLibPlugin.CSCoreLib; import me.mrCookieSlime.CSCoreLibPlugin.CSCoreLib;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AContainer; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AContainer;
@ -175,10 +182,14 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon {
command.register(); command.register();
registry.load(config); registry.load(config);
} else if (getServer().getPluginManager().isPluginEnabled("CS-CoreLib")) { } else if (getServer().getPluginManager().isPluginEnabled("CS-CoreLib")) {
getLogger().log(Level.INFO, "CS-CoreLib was detected!");
long timestamp = System.nanoTime(); long timestamp = System.nanoTime();
PaperLib.suggestPaper(this); PaperLib.suggestPaper(this);
if (PaperLib.isPaper()) {
getLogger().log(Level.INFO, "Paper was detected! Performance optimizations have been applied.");
}
// We wanna ensure that the Server uses a compatible version of Minecraft // We wanna ensure that the Server uses a compatible version of Minecraft
if (isVersionUnsupported()) { if (isVersionUnsupported()) {
getServer().getPluginManager().disablePlugin(this); getServer().getPluginManager().disablePlugin(this);
@ -229,6 +240,9 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon {
getLogger().log(Level.INFO, "Loading GEO-Resources..."); getLogger().log(Level.INFO, "Loading GEO-Resources...");
GEOResourcesSetup.setup(); GEOResourcesSetup.setup();
getLogger().log(Level.INFO, "Loading Tags...");
loadTags();
getLogger().log(Level.INFO, "Loading items..."); getLogger().log(Level.INFO, "Loading items...");
loadItems(); loadItems();
@ -267,7 +281,10 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon {
autoSavingService.start(this, config.getInt("options.auto-save-delay-in-minutes")); autoSavingService.start(this, config.getInt("options.auto-save-delay-in-minutes"));
ticker.start(this); ticker.start(this);
getLogger().log(Level.INFO, "Loading Third-Party plugin integrations...");
thirdPartySupportService.start(); thirdPartySupportService.start();
gitHubService.start(this); gitHubService.start(this);
// Hooray! // Hooray!
@ -311,7 +328,7 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon {
String currentVersion = ReflectionUtils.getVersion(); String currentVersion = ReflectionUtils.getVersion();
if (currentVersion.startsWith("v")) { if (currentVersion.startsWith("v")) {
for (MinecraftVersion version : MinecraftVersion.values) { for (MinecraftVersion version : MinecraftVersion.valuesCache) {
if (version.matches(currentVersion)) { if (version.matches(currentVersion)) {
minecraftVersion = version; minecraftVersion = version;
return false; return false;
@ -338,7 +355,7 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon {
private Collection<String> getSupportedVersions() { private Collection<String> getSupportedVersions() {
List<String> list = new ArrayList<>(); List<String> list = new ArrayList<>();
for (MinecraftVersion version : MinecraftVersion.values) { for (MinecraftVersion version : MinecraftVersion.valuesCache) {
if (version != MinecraftVersion.UNKNOWN) { if (version != MinecraftVersion.UNKNOWN) {
list.add(version.getName()); list.add(version.getName());
} }
@ -442,7 +459,6 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon {
new DeathpointListener(this); new DeathpointListener(this);
new ExplosionsListener(this); new ExplosionsListener(this);
new DebugFishListener(this); new DebugFishListener(this);
new VanillaMachinesListener(this);
new FireworksListener(this); new FireworksListener(this);
new WitherListener(this); new WitherListener(this);
new IronGolemListener(this); new IronGolemListener(this);
@ -450,6 +466,12 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon {
new MobDropListener(this); new MobDropListener(this);
new VillagerTradingListener(this); new VillagerTradingListener(this);
new ElytraCrashListener(this); new ElytraCrashListener(this);
new CraftingTableListener(this);
new AnvilListener(this);
new BrewingStandListener(this);
new CauldronListener(this);
new GrindstoneListener(this);
new CartographyTableListener(this);
if (minecraftVersion.isAtLeast(MinecraftVersion.MINECRAFT_1_15)) { if (minecraftVersion.isAtLeast(MinecraftVersion.MINECRAFT_1_15)) {
new BeeListener(this); new BeeListener(this);
@ -491,6 +513,16 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon {
new PlayerProfileListener(this); new PlayerProfileListener(this);
} }
private void loadTags() {
for (SlimefunTag tag : SlimefunTag.valuesCache) {
try {
tag.reload();
} catch (TagMisconfigurationException e) {
getLogger().log(Level.SEVERE, e, () -> "Failed to load Tag: " + tag.name());
}
}
}
private void loadItems() { private void loadItems() {
try { try {
SlimefunItemSetup.setup(this); SlimefunItemSetup.setup(this);

View File

@ -208,7 +208,7 @@ public class BookSlimefunGuide implements SlimefunGuideImplementation {
} }
private void addSlimefunItem(Category category, int page, Player p, PlayerProfile profile, SlimefunItem item, List<ChatComponent> items) { private void addSlimefunItem(Category category, int page, Player p, PlayerProfile profile, SlimefunItem item, List<ChatComponent> items) {
NamespacedKey key = new NamespacedKey(SlimefunPlugin.instance(), item.getID().toLowerCase(Locale.ROOT)); NamespacedKey key = new NamespacedKey(SlimefunPlugin.instance(), item.getId().toLowerCase(Locale.ROOT));
if (!Slimefun.hasUnlocked(p, item, false) && item.getResearch() != null) { if (!Slimefun.hasUnlocked(p, item, false) && item.getResearch() != null) {
Research research = item.getResearch(); Research research = item.getResearch();

View File

@ -1,7 +1,5 @@
package io.github.thebusybiscuit.slimefun4.implementation.guide; package io.github.thebusybiscuit.slimefun4.implementation.guide;
import javax.annotation.Nonnull;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.LinkedList; import java.util.LinkedList;
@ -10,6 +8,8 @@ import java.util.Locale;
import java.util.Optional; import java.util.Optional;
import java.util.logging.Level; import java.util.logging.Level;
import javax.annotation.Nonnull;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.Sound; import org.bukkit.Sound;
@ -26,7 +26,6 @@ import io.github.thebusybiscuit.cscorelib2.chat.ChatInput;
import io.github.thebusybiscuit.cscorelib2.inventory.ItemUtils; import io.github.thebusybiscuit.cscorelib2.inventory.ItemUtils;
import io.github.thebusybiscuit.cscorelib2.item.CustomItem; import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
import io.github.thebusybiscuit.cscorelib2.recipes.MinecraftRecipe; import io.github.thebusybiscuit.cscorelib2.recipes.MinecraftRecipe;
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile; import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile;
import io.github.thebusybiscuit.slimefun4.core.attributes.RecipeDisplayItem; import io.github.thebusybiscuit.slimefun4.core.attributes.RecipeDisplayItem;
import io.github.thebusybiscuit.slimefun4.core.categories.FlexCategory; import io.github.thebusybiscuit.slimefun4.core.categories.FlexCategory;
@ -68,18 +67,12 @@ public class ChestSlimefunGuide implements SlimefunGuideImplementation {
private final ItemStack item; private final ItemStack item;
private final int[] recipeSlots = { 3, 4, 5, 12, 13, 14, 21, 22, 23 }; private final int[] recipeSlots = { 3, 4, 5, 12, 13, 14, 21, 22, 23 };
private final Sound sound; private final Sound sound = Sound.ITEM_BOOK_PAGE_TURN;
private final boolean showVanillaRecipes; private final boolean showVanillaRecipes;
public ChestSlimefunGuide(boolean vanillaRecipes) { public ChestSlimefunGuide(boolean vanillaRecipes) {
showVanillaRecipes = vanillaRecipes; showVanillaRecipes = vanillaRecipes;
item = new SlimefunGuideItem(this, "&aSlimefun Guide &7(Chest GUI)"); item = new SlimefunGuideItem(this, "&aSlimefun Guide &7(Chest GUI)");
if (SlimefunPlugin.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_14)) {
sound = Sound.ITEM_BOOK_PAGE_TURN;
} else {
sound = Sound.ENTITY_BAT_TAKEOFF;
}
} }
@Override @Override
@ -233,16 +226,22 @@ public class ChestSlimefunGuide implements SlimefunGuideImplementation {
menu.addItem(46, ChestMenuUtils.getPreviousButton(p, page, pages)); menu.addItem(46, ChestMenuUtils.getPreviousButton(p, page, pages));
menu.addMenuClickHandler(46, (pl, slot, item, action) -> { menu.addMenuClickHandler(46, (pl, slot, item, action) -> {
int next = page - 1; int next = page - 1;
if (next != page && next > 0)
if (next != page && next > 0) {
openCategory(profile, category, next); openCategory(profile, category, next);
}
return false; return false;
}); });
menu.addItem(52, ChestMenuUtils.getNextButton(p, page, pages)); menu.addItem(52, ChestMenuUtils.getNextButton(p, page, pages));
menu.addMenuClickHandler(52, (pl, slot, item, action) -> { menu.addMenuClickHandler(52, (pl, slot, item, action) -> {
int next = page + 1; int next = page + 1;
if (next != page && next <= pages)
if (next != page && next <= pages) {
openCategory(profile, category, next); openCategory(profile, category, next);
}
return false; return false;
}); });

View File

@ -2,6 +2,10 @@ package io.github.thebusybiscuit.slimefun4.implementation.items.altar;
import java.util.Optional; import java.util.Optional;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.GameMode; import org.bukkit.GameMode;
import org.bukkit.Location; import org.bukkit.Location;
@ -17,7 +21,9 @@ import org.bukkit.util.Vector;
import io.github.thebusybiscuit.cscorelib2.chat.ChatColors; import io.github.thebusybiscuit.cscorelib2.chat.ChatColors;
import io.github.thebusybiscuit.cscorelib2.inventory.ItemUtils; import io.github.thebusybiscuit.cscorelib2.inventory.ItemUtils;
import io.github.thebusybiscuit.cscorelib2.item.CustomItem; import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
import io.github.thebusybiscuit.slimefun4.core.handlers.BlockDispenseHandler;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.AncientAltarListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.AncientAltarListener;
import io.github.thebusybiscuit.slimefun4.implementation.tasks.AncientAltarTask; import io.github.thebusybiscuit.slimefun4.implementation.tasks.AncientAltarTask;
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils; import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
@ -39,14 +45,15 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
* @see AncientAltarTask * @see AncientAltarTask
* *
*/ */
public class AncientPedestal extends SlimefunItem { public class AncientPedestal extends SimpleSlimefunItem<BlockDispenseHandler> {
public static final String ITEM_PREFIX = ChatColors.color("&dALTAR &3Probe - &e"); public static final String ITEM_PREFIX = ChatColors.color("&dALTAR &3Probe - &e");
@ParametersAreNonnullByDefault
public AncientPedestal(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe, ItemStack recipeOutput) { public AncientPedestal(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe, ItemStack recipeOutput) {
super(category, item, recipeType, recipe, recipeOutput); super(category, item, recipeType, recipe, recipeOutput);
SlimefunItem.registerBlockHandler(getID(), (p, b, tool, reason) -> { SlimefunItem.registerBlockHandler(getId(), (p, b, tool, reason) -> {
Optional<Item> entity = getPlacedItem(b); Optional<Item> entity = getPlacedItem(b);
if (entity.isPresent()) { if (entity.isPresent()) {
@ -63,7 +70,13 @@ public class AncientPedestal extends SlimefunItem {
}); });
} }
public Optional<Item> getPlacedItem(Block pedestal) { @Override
public BlockDispenseHandler getItemHandler() {
return (e, d, block, machine) -> e.setCancelled(true);
}
@Nonnull
public Optional<Item> getPlacedItem(@Nonnull Block pedestal) {
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)) {
@ -75,7 +88,7 @@ public class AncientPedestal extends SlimefunItem {
return Optional.empty(); return Optional.empty();
} }
private boolean testItem(Entity n) { private boolean testItem(@Nullable Entity n) {
if (n instanceof Item && n.isValid()) { if (n instanceof Item && n.isValid()) {
Item item = (Item) n; Item item = (Item) n;
ItemMeta meta = item.getItemStack().getItemMeta(); ItemMeta meta = item.getItemStack().getItemMeta();
@ -86,7 +99,8 @@ public class AncientPedestal extends SlimefunItem {
} }
} }
public ItemStack getOriginalItemStack(Item item) { @Nonnull
public ItemStack getOriginalItemStack(@Nonnull Item item) {
ItemStack stack = item.getItemStack().clone(); ItemStack stack = item.getItemStack().clone();
String customName = item.getCustomName(); String customName = item.getCustomName();
@ -108,7 +122,7 @@ public class AncientPedestal extends SlimefunItem {
return stack; return stack;
} }
public void placeItem(Player p, Block b) { public void placeItem(@Nonnull Player p, @Nonnull Block b) {
ItemStack hand = p.getInventory().getItemInMainHand(); ItemStack hand = p.getInventory().getItemInMainHand();
ItemStack displayItem = new CustomItem(hand, ITEM_PREFIX + System.nanoTime()); ItemStack displayItem = new CustomItem(hand, ITEM_PREFIX + System.nanoTime());
displayItem.setAmount(1); displayItem.setAmount(1);

View File

@ -0,0 +1,34 @@
package io.github.thebusybiscuit.slimefun4.implementation.items.androids;
import javax.annotation.ParametersAreNonnullByDefault;
import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.slimefun4.core.handlers.BlockDispenseHandler;
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
/**
* The {@link AndroidInterface} are inventories used to interact with a {@link ProgrammableAndroid}.
* There are two variants of interfaces, fuel and items.
*
* @author TheBusyBiscuit
*
* @see ProgrammableAndroid
*
*/
public class AndroidInterface extends SimpleSlimefunItem<BlockDispenseHandler> {
@ParametersAreNonnullByDefault
public AndroidInterface(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(category, item, recipeType, recipe);
}
@Override
public BlockDispenseHandler getItemHandler() {
return (e, d, block, machine) -> e.setCancelled(true);
}
}

View File

@ -10,8 +10,6 @@ import org.bukkit.block.data.Ageable;
import org.bukkit.block.data.BlockData; import org.bukkit.block.data.BlockData;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
@ -57,10 +55,6 @@ public class FarmerAndroid extends ProgrammableAndroid {
private ItemStack getDropFromCrop(Material crop) { private ItemStack getDropFromCrop(Material crop) {
Random random = ThreadLocalRandom.current(); Random random = ThreadLocalRandom.current();
if (SlimefunPlugin.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_14) && crop == Material.SWEET_BERRY_BUSH) {
return new ItemStack(Material.SWEET_BERRIES, random.nextInt(3) + 1);
}
switch (crop) { switch (crop) {
case WHEAT: case WHEAT:
return new ItemStack(Material.WHEAT, random.nextInt(2) + 1); return new ItemStack(Material.WHEAT, random.nextInt(2) + 1);
@ -74,6 +68,8 @@ public class FarmerAndroid extends ProgrammableAndroid {
return new ItemStack(Material.COCOA_BEANS, random.nextInt(3) + 1); return new ItemStack(Material.COCOA_BEANS, random.nextInt(3) + 1);
case NETHER_WART: case NETHER_WART:
return new ItemStack(Material.NETHER_WART, random.nextInt(3) + 1); 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: default:
return null; return null;
} }

View File

@ -4,14 +4,12 @@ import java.util.concurrent.ThreadLocalRandom;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.Sound; import org.bukkit.Sound;
import org.bukkit.Tag;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.block.BlockFace; import org.bukkit.block.BlockFace;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.cscorelib2.collections.RandomizedSet; import io.github.thebusybiscuit.cscorelib2.collections.RandomizedSet;
import io.github.thebusybiscuit.cscorelib2.materials.MaterialCollections;
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
@ -25,7 +23,7 @@ public class FisherAndroid extends ProgrammableAndroid {
super(category, tier, item, recipeType, recipe); super(category, tier, item, recipeType, recipe);
// Fish // Fish
for (Material fish : MaterialCollections.getAllFishItems()) { for (Material fish : Tag.ITEMS_FISHES.getValues()) {
fishingLoot.add(new ItemStack(fish), 25); fishingLoot.add(new ItemStack(fish), 25);
} }
@ -37,10 +35,7 @@ public class FisherAndroid extends ProgrammableAndroid {
fishingLoot.add(new ItemStack(Material.STICK), 5); fishingLoot.add(new ItemStack(Material.STICK), 5);
fishingLoot.add(new ItemStack(Material.ROTTEN_FLESH), 3); fishingLoot.add(new ItemStack(Material.ROTTEN_FLESH), 3);
fishingLoot.add(new ItemStack(Material.LEATHER), 2); fishingLoot.add(new ItemStack(Material.LEATHER), 2);
fishingLoot.add(new ItemStack(Material.BAMBOO), 3);
if (SlimefunPlugin.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_14)) {
fishingLoot.add(new ItemStack(Material.BAMBOO), 3);
}
// "loot" // "loot"
fishingLoot.add(new ItemStack(Material.SADDLE), 1); fishingLoot.add(new ItemStack(Material.SADDLE), 1);

View File

@ -146,18 +146,18 @@ enum Instruction {
}); });
private static final Map<String, Instruction> nameLookup = new HashMap<>(); private static final Map<String, Instruction> nameLookup = new HashMap<>();
public static final Instruction[] values = values(); public static final Instruction[] valuesCache = values();
static {
for (Instruction instruction : valuesCache) {
nameLookup.put(instruction.name(), instruction);
}
}
private final ItemStack item; private final ItemStack item;
private final AndroidType type; private final AndroidType type;
private final AndroidAction method; private final AndroidAction method;
static {
for (Instruction instruction : values) {
nameLookup.put(instruction.name(), instruction);
}
}
@ParametersAreNonnullByDefault @ParametersAreNonnullByDefault
Instruction(AndroidType type, HeadTexture head, @Nullable AndroidAction method) { Instruction(AndroidType type, HeadTexture head, @Nullable AndroidAction method) {
this.type = type; this.type = type;
@ -198,7 +198,7 @@ enum Instruction {
* @return The {@link Instruction} or null if it does not exist. * @return The {@link Instruction} or null if it does not exist.
*/ */
@Nullable @Nullable
public static Instruction getFromCache(@Nonnull String value) { public static Instruction getInstruction(@Nonnull String value) {
Validate.notNull(value, "An Instruction cannot be null!"); Validate.notNull(value, "An Instruction cannot be null!");
return nameLookup.get(value); return nameLookup.get(value);
} }

View File

@ -11,10 +11,10 @@ import org.bukkit.block.Block;
import org.bukkit.block.BlockFace; import org.bukkit.block.BlockFace;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.cscorelib2.materials.MaterialCollections;
import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction; import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction;
import io.github.thebusybiscuit.slimefun4.api.events.AndroidMineEvent; import io.github.thebusybiscuit.slimefun4.api.events.AndroidMineEvent;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.utils.tags.SlimefunTag;
import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
@ -40,7 +40,7 @@ public class MinerAndroid extends ProgrammableAndroid {
protected void dig(Block b, BlockMenu menu, Block block) { protected void dig(Block b, BlockMenu menu, Block block) {
Collection<ItemStack> drops = block.getDrops(effectivePickaxe); Collection<ItemStack> drops = block.getDrops(effectivePickaxe);
if (!MaterialCollections.getAllUnbreakableBlocks().contains(block.getType()) && !drops.isEmpty()) { if (!SlimefunTag.UNBREAKABLE_MATERIALS.isTagged(block.getType()) && !drops.isEmpty()) {
OfflinePlayer owner = Bukkit.getOfflinePlayer(UUID.fromString(BlockStorage.getLocationInfo(b.getLocation(), "owner"))); OfflinePlayer owner = Bukkit.getOfflinePlayer(UUID.fromString(BlockStorage.getLocationInfo(b.getLocation(), "owner")));
if (SlimefunPlugin.getProtectionManager().hasPermission(owner, block.getLocation(), ProtectableAction.BREAK_BLOCK)) { if (SlimefunPlugin.getProtectionManager().hasPermission(owner, block.getLocation(), ProtectableAction.BREAK_BLOCK)) {
@ -71,7 +71,7 @@ public class MinerAndroid extends ProgrammableAndroid {
protected void moveAndDig(Block b, BlockMenu menu, BlockFace face, Block block) { protected void moveAndDig(Block b, BlockMenu menu, BlockFace face, Block block) {
Collection<ItemStack> drops = block.getDrops(effectivePickaxe); Collection<ItemStack> drops = block.getDrops(effectivePickaxe);
if (!MaterialCollections.getAllUnbreakableBlocks().contains(block.getType()) && !drops.isEmpty()) { if (!SlimefunTag.UNBREAKABLE_MATERIALS.isTagged(block.getType()) && !drops.isEmpty()) {
OfflinePlayer owner = Bukkit.getOfflinePlayer(UUID.fromString(BlockStorage.getLocationInfo(b.getLocation(), "owner"))); OfflinePlayer owner = Bukkit.getOfflinePlayer(UUID.fromString(BlockStorage.getLocationInfo(b.getLocation(), "owner")));
if (SlimefunPlugin.getProtectionManager().hasPermission(owner, block.getLocation(), ProtectableAction.BREAK_BLOCK)) { if (SlimefunPlugin.getProtectionManager().hasPermission(owner, block.getLocation(), ProtectableAction.BREAK_BLOCK)) {

View File

@ -81,7 +81,7 @@ public class ProgrammableAndroid extends SlimefunItem implements InventoryBlock,
texture = item.getSkullTexture().orElse(null); texture = item.getSkullTexture().orElse(null);
registerDefaultFuelTypes(); registerDefaultFuelTypes();
new BlockMenuPreset(getID(), "Programmable Android") { new BlockMenuPreset(getId(), "Programmable Android") {
@Override @Override
public void init() { public void init() {
@ -131,7 +131,7 @@ public class ProgrammableAndroid extends SlimefunItem implements InventoryBlock,
} }
}; };
registerBlockHandler(getID(), (p, b, stack, reason) -> { registerBlockHandler(getId(), (p, b, stack, reason) -> {
boolean allow = reason == UnregisterReason.PLAYER_BREAK && (BlockStorage.getLocationInfo(b.getLocation(), "owner").equals(p.getUniqueId().toString()) || p.hasPermission("slimefun.android.bypass")); boolean allow = reason == UnregisterReason.PLAYER_BREAK && (BlockStorage.getLocationInfo(b.getLocation(), "owner").equals(p.getUniqueId().toString()) || p.hasPermission("slimefun.android.bypass"));
if (allow) { if (allow) {
@ -257,7 +257,7 @@ public class ProgrammableAndroid extends SlimefunItem implements InventoryBlock,
return false; return false;
}); });
} else { } else {
Instruction instruction = Instruction.getFromCache(script[i]); Instruction instruction = Instruction.getInstruction(script[i]);
if (instruction == null) { if (instruction == null) {
SlimefunPlugin.instance().getLogger().log(Level.WARNING, "Failed to parse Android instruction: {0}, maybe your server is out of date?", script[i]); SlimefunPlugin.instance().getLogger().log(Level.WARNING, "Failed to parse Android instruction: {0}, maybe your server is out of date?", script[i]);
@ -493,7 +493,7 @@ public class ProgrammableAndroid extends SlimefunItem implements InventoryBlock,
protected List<Instruction> getValidScriptInstructions() { protected List<Instruction> getValidScriptInstructions() {
List<Instruction> list = new ArrayList<>(); List<Instruction> list = new ArrayList<>();
for (Instruction part : Instruction.values) { for (Instruction part : Instruction.valuesCache) {
if (part == Instruction.START || part == Instruction.REPEAT) { if (part == Instruction.START || part == Instruction.REPEAT) {
continue; continue;
} }
@ -646,7 +646,7 @@ public class ProgrammableAndroid extends SlimefunItem implements InventoryBlock,
} }
BlockStorage.addBlockInfo(b, "fuel", String.valueOf(fuel - 1)); BlockStorage.addBlockInfo(b, "fuel", String.valueOf(fuel - 1));
Instruction instruction = Instruction.getFromCache(script[index]); Instruction instruction = Instruction.getInstruction(script[index]);
if (instruction == null) { if (instruction == null) {
SlimefunPlugin.instance().getLogger().log(Level.WARNING, "Failed to parse Android instruction: {0}, maybe your server is out of date?", script[index]); SlimefunPlugin.instance().getLogger().log(Level.WARNING, "Failed to parse Android instruction: {0}, maybe your server is out of date?", script[index]);

View File

@ -9,6 +9,9 @@ import java.util.List;
import java.util.UUID; import java.util.UUID;
import java.util.logging.Level; import java.util.logging.Level;
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;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
@ -22,6 +25,12 @@ import io.github.thebusybiscuit.slimefun4.utils.ChatUtils;
import io.github.thebusybiscuit.slimefun4.utils.NumberUtils; import io.github.thebusybiscuit.slimefun4.utils.NumberUtils;
import me.mrCookieSlime.Slimefun.api.Slimefun; import me.mrCookieSlime.Slimefun.api.Slimefun;
/**
* A {@link Script} represents runnable code for a {@link ProgrammableAndroid}.
*
* @author TheBusyBiscuit
*
*/
public final class Script { public final class Script {
private final Config config; private final Config config;
@ -29,7 +38,13 @@ public final class Script {
private final String author; private final String author;
private final String code; private final String code;
private Script(Config config) { /**
* This constructs a new {@link Script} from the given {@link Config}.
*
* @param config
* The {@link Config}
*/
private Script(@Nonnull Config config) {
Validate.notNull(config); Validate.notNull(config);
this.config = config; this.config = config;
@ -52,6 +67,7 @@ public final class Script {
* *
* @return The name * @return The name
*/ */
@Nonnull
public String getName() { public String getName() {
return name; return name;
} }
@ -62,6 +78,7 @@ public final class Script {
* *
* @return The author of this {@link Script} * @return The author of this {@link Script}
*/ */
@Nonnull
public String getAuthor() { public String getAuthor() {
return author; return author;
} }
@ -73,6 +90,7 @@ public final class Script {
* *
* @return The code for this {@link Script} * @return The code for this {@link Script}
*/ */
@Nonnull
public String getSourceCode() { public String getSourceCode() {
return code; return code;
} }
@ -86,7 +104,7 @@ public final class Script {
* *
* @return Whether the given {@link OfflinePlayer} is the author of this {@link Script}. * @return Whether the given {@link OfflinePlayer} is the author of this {@link Script}.
*/ */
public boolean isAuthor(OfflinePlayer p) { public boolean isAuthor(@Nonnull OfflinePlayer p) {
return p.getUniqueId().equals(config.getUUID("author")); return p.getUniqueId().equals(config.getUUID("author"));
} }
@ -99,7 +117,7 @@ public final class Script {
* *
* @return Whether the given {@link Player} is able to rate this {@link Script} * @return Whether the given {@link Player} is able to rate this {@link Script}
*/ */
public boolean canRate(Player p) { public boolean canRate(@Nonnull Player p) {
if (isAuthor(p)) { if (isAuthor(p)) {
return false; return false;
} }
@ -109,7 +127,8 @@ public final class Script {
return !upvoters.contains(p.getUniqueId().toString()) && !downvoters.contains(p.getUniqueId().toString()); return !upvoters.contains(p.getUniqueId().toString()) && !downvoters.contains(p.getUniqueId().toString());
} }
ItemStack getAsItemStack(ProgrammableAndroid android, Player p) { @Nonnull
ItemStack getAsItemStack(@Nonnull ProgrammableAndroid android, @Nonnull Player p) {
List<String> lore = new LinkedList<>(); List<String> lore = new LinkedList<>();
lore.add("&7by &r" + getAuthor()); lore.add("&7by &r" + getAuthor());
lore.add(""); lore.add("");
@ -128,6 +147,7 @@ public final class Script {
return new CustomItem(android.getItem(), "&b" + getName(), lore.toArray(new String[0])); return new CustomItem(android.getItem(), "&b" + getName(), lore.toArray(new String[0]));
} }
@Nonnull
private String getScriptRatingPercentage() { private String getScriptRatingPercentage() {
float percentage = getRating(); float percentage = getRating();
return NumberUtils.getColorFromPercentage(percentage) + String.valueOf(percentage) + ChatColor.RESET + "% "; return NumberUtils.getColorFromPercentage(percentage) + String.valueOf(percentage) + ChatColor.RESET + "% ";
@ -181,7 +201,7 @@ public final class Script {
config.save(); config.save();
} }
public void rate(Player p, boolean positive) { public void rate(@Nonnull Player p, boolean positive) {
config.reload(); config.reload();
String path = "rating." + (positive ? "positive" : "negative"); String path = "rating." + (positive ? "positive" : "negative");
@ -192,7 +212,8 @@ public final class Script {
config.save(); config.save();
} }
public static List<Script> getUploadedScripts(AndroidType androidType) { @Nonnull
public static List<Script> getUploadedScripts(@Nonnull AndroidType androidType) {
List<Script> scripts = new LinkedList<>(); List<Script> scripts = new LinkedList<>();
loadScripts(scripts, androidType); loadScripts(scripts, androidType);
@ -205,7 +226,7 @@ public final class Script {
return scripts; return scripts;
} }
private static void loadScripts(List<Script> scripts, AndroidType type) { private static void loadScripts(@Nonnull List<Script> scripts, @Nonnull AndroidType type) {
File directory = new File("plugins/Slimefun/scripts/" + type.name()); File directory = new File("plugins/Slimefun/scripts/" + type.name());
if (!directory.exists()) { if (!directory.exists()) {
directory.mkdirs(); directory.mkdirs();
@ -228,6 +249,7 @@ public final class Script {
} }
} }
@ParametersAreNonnullByDefault
public static void upload(Player p, AndroidType androidType, int id, String name, String code) { public static void upload(Player p, AndroidType androidType, int id, String name, String code) {
Config config = new Config("plugins/Slimefun/scripts/" + androidType.name() + '/' + p.getName() + ' ' + id + ".sfs"); Config config = new Config("plugins/Slimefun/scripts/" + androidType.name() + '/' + p.getName() + ' ' + id + ".sfs");

View File

@ -1,6 +1,9 @@
package io.github.thebusybiscuit.slimefun4.implementation.items.backpacks; package io.github.thebusybiscuit.slimefun4.implementation.items.backpacks;
import org.bukkit.Material; import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
@ -9,6 +12,7 @@ import io.github.thebusybiscuit.slimefun4.core.handlers.ItemUseHandler;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem; import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.BackpackListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.BackpackListener;
import io.github.thebusybiscuit.slimefun4.utils.tags.SlimefunTag;
import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
@ -28,6 +32,7 @@ public class SlimefunBackpack extends SimpleSlimefunItem<ItemUseHandler> {
private final int size; private final int size;
@ParametersAreNonnullByDefault
public SlimefunBackpack(int size, Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { public SlimefunBackpack(int size, Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(category, item, recipeType, recipe); super(category, item, recipeType, recipe);
@ -55,9 +60,9 @@ public class SlimefunBackpack extends SimpleSlimefunItem<ItemUseHandler> {
* *
* @return Whether the given {@link ItemStack} is allowed to be put into this {@link SlimefunBackpack} * @return Whether the given {@link ItemStack} is allowed to be put into this {@link SlimefunBackpack}
*/ */
public boolean isItemAllowed(ItemStack item, SlimefunItem itemAsSlimefunItem) { public boolean isItemAllowed(@Nonnull ItemStack item, @Nullable SlimefunItem itemAsSlimefunItem) {
// Shulker Boxes are not allowed! // Shulker Boxes are not allowed!
if (item.getType() == Material.SHULKER_BOX || item.getType().toString().endsWith("_SHULKER_BOX")) { if (SlimefunTag.SHULKER_BOXES.isTagged(item.getType())) {
return false; return false;
} }

View File

@ -2,7 +2,6 @@ package io.github.thebusybiscuit.slimefun4.implementation.items.blocks;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import java.util.stream.Collectors;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Effect; import org.bukkit.Effect;
@ -18,14 +17,15 @@ import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import io.github.thebusybiscuit.cscorelib2.item.CustomItem; import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
import io.github.thebusybiscuit.cscorelib2.materials.MaterialCollections;
import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction; import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction;
import io.github.thebusybiscuit.slimefun4.api.events.BlockPlacerPlaceEvent; import io.github.thebusybiscuit.slimefun4.api.events.BlockPlacerPlaceEvent;
import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting; import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting;
import io.github.thebusybiscuit.slimefun4.api.items.settings.MaterialTagSetting;
import io.github.thebusybiscuit.slimefun4.core.attributes.NotPlaceable; import io.github.thebusybiscuit.slimefun4.core.attributes.NotPlaceable;
import io.github.thebusybiscuit.slimefun4.core.handlers.BlockDispenseHandler; import io.github.thebusybiscuit.slimefun4.core.handlers.BlockDispenseHandler;
import io.github.thebusybiscuit.slimefun4.core.handlers.BlockPlaceHandler; import io.github.thebusybiscuit.slimefun4.core.handlers.BlockPlaceHandler;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.utils.tags.SlimefunTag;
import io.papermc.lib.PaperLib; import io.papermc.lib.PaperLib;
import io.papermc.lib.features.blockstatesnapshot.BlockStateSnapshotResult; import io.papermc.lib.features.blockstatesnapshot.BlockStateSnapshotResult;
import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Lists.RecipeType;
@ -47,7 +47,7 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
*/ */
public class BlockPlacer extends SlimefunItem { public class BlockPlacer extends SlimefunItem {
private final ItemSetting<List<String>> blacklist = new ItemSetting<>("unplaceable-blocks", MaterialCollections.getAllUnbreakableBlocks().stream().map(Material::name).collect(Collectors.toList())); private final ItemSetting<List<String>> blacklist = new MaterialTagSetting("unplaceable-blocks", SlimefunTag.UNBREAKABLE_MATERIALS);
public BlockPlacer(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { public BlockPlacer(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(category, item, recipeType, recipe); super(category, item, recipeType, recipe);
@ -72,10 +72,13 @@ public class BlockPlacer extends SlimefunItem {
private BlockDispenseHandler onBlockDispense() { private BlockDispenseHandler onBlockDispense() {
return (e, dispenser, facedBlock, machine) -> { return (e, dispenser, facedBlock, machine) -> {
if (!hasPermission(dispenser, facedBlock)) { if (!hasPermission(dispenser, facedBlock)) {
e.setCancelled(true);
return; return;
} }
if (isShulkerBox(e.getItem().getType())) { Material material = e.getItem().getType();
if (SlimefunTag.SHULKER_BOXES.isTagged(material)) {
// Since vanilla Dispensers can already place Shulker boxes, we // Since vanilla Dispensers can already place Shulker boxes, we
// simply fallback to the vanilla behaviour. // simply fallback to the vanilla behaviour.
return; return;
@ -83,7 +86,14 @@ public class BlockPlacer extends SlimefunItem {
e.setCancelled(true); e.setCancelled(true);
if (facedBlock.isEmpty() && e.getItem().getType().isBlock() && !isBlacklisted(e.getItem().getType())) { if (!material.isBlock() || SlimefunTag.BLOCK_PLACER_IGNORED_MATERIALS.isTagged(material)) {
// Some materials cannot be reliably placed, like beds, it would look
// kinda wonky, so we just ignore these altogether.
// The event has already been cancelled too, so they won't drop.
return;
}
if (facedBlock.isEmpty() && !isBlacklisted(material)) {
SlimefunItem item = SlimefunItem.getByItem(e.getItem()); SlimefunItem item = SlimefunItem.getByItem(e.getItem());
if (item != null) { if (item != null) {
@ -123,10 +133,6 @@ public class BlockPlacer extends SlimefunItem {
return SlimefunPlugin.getProtectionManager().hasPermission(player, target, ProtectableAction.PLACE_BLOCK); return SlimefunPlugin.getProtectionManager().hasPermission(player, target, ProtectableAction.PLACE_BLOCK);
} }
private boolean isShulkerBox(Material type) {
return type == Material.SHULKER_BOX || type.name().endsWith("_SHULKER_BOX");
}
private boolean isBlacklisted(Material type) { private boolean isBlacklisted(Material type) {
for (String blockType : blacklist.getValue()) { for (String blockType : blacklist.getValue()) {
if (type.toString().equals(blockType)) { if (type.toString().equals(blockType)) {
@ -147,7 +153,7 @@ public class BlockPlacer extends SlimefunItem {
block.setType(item.getType()); block.setType(item.getType());
block.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, item.getType()); block.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, item.getType());
BlockStorage.store(block, sfItem.getID()); BlockStorage.store(block, sfItem.getId());
handler.onBlockPlacerPlace(e); handler.onBlockPlacerPlace(e);
if (dispenser.getInventory().containsAtLeast(item, 2)) { if (dispenser.getInventory().containsAtLeast(item, 2)) {
@ -162,7 +168,7 @@ public class BlockPlacer extends SlimefunItem {
block.setType(item.getType()); block.setType(item.getType());
block.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, item.getType()); block.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, item.getType());
BlockStorage.store(block, sfItem.getID()); BlockStorage.store(block, sfItem.getId());
if (dispenser.getInventory().containsAtLeast(item, 2)) { if (dispenser.getInventory().containsAtLeast(item, 2)) {
dispenser.getInventory().removeItem(new CustomItem(item, 1)); dispenser.getInventory().removeItem(new CustomItem(item, 1));

View File

@ -17,13 +17,14 @@ import org.bukkit.block.data.Waterlogged;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.cscorelib2.materials.MaterialCollections;
import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction; import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction;
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
import io.github.thebusybiscuit.slimefun4.core.attributes.RecipeDisplayItem; import io.github.thebusybiscuit.slimefun4.core.attributes.RecipeDisplayItem;
import io.github.thebusybiscuit.slimefun4.core.handlers.BlockUseHandler; import io.github.thebusybiscuit.slimefun4.core.handlers.BlockUseHandler;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem; import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils; import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
import io.github.thebusybiscuit.slimefun4.utils.tags.SlimefunTag;
import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.api.BlockStorage; import me.mrCookieSlime.Slimefun.api.BlockStorage;
@ -67,11 +68,19 @@ public class Crucible extends SimpleSlimefunItem<BlockUseHandler> implements Rec
items.add(new ItemStack(Material.WATER_BUCKET)); items.add(new ItemStack(Material.WATER_BUCKET));
} }
for (Material sapling : MaterialCollections.getAllTerracottaColors()) { for (Material sapling : SlimefunTag.TERRACOTTA.getValues()) {
items.add(new ItemStack(sapling, 12)); items.add(new ItemStack(sapling, 12));
items.add(new ItemStack(Material.LAVA_BUCKET)); items.add(new ItemStack(Material.LAVA_BUCKET));
} }
if (SlimefunPlugin.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_16)) {
items.add(new ItemStack(Material.BLACKSTONE, 8));
items.add(new ItemStack(Material.LAVA_BUCKET));
items.add(new ItemStack(Material.BASALT, 12));
items.add(new ItemStack(Material.LAVA_BUCKET));
}
return items; return items;
} }

View File

@ -11,6 +11,7 @@ import org.bukkit.inventory.ItemStack;
import org.bukkit.util.Vector; import org.bukkit.util.Vector;
import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting; import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting;
import io.github.thebusybiscuit.slimefun4.api.items.settings.DoubleRangeSetting;
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem; import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils; import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config; import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config;
@ -24,7 +25,7 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
public class InfusedHopper extends SimpleSlimefunItem<BlockTicker> { public class InfusedHopper extends SimpleSlimefunItem<BlockTicker> {
private final ItemSetting<Boolean> silent = new ItemSetting<>("silent", false); private final ItemSetting<Boolean> silent = new ItemSetting<>("silent", false);
private final ItemSetting<Double> radius = new ItemSetting<>("radius", 3.5); private final ItemSetting<Double> radius = new DoubleRangeSetting("radius", 0.1, 3.5, Double.MAX_VALUE);
public InfusedHopper(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { public InfusedHopper(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(category, item, recipeType, recipe); super(category, item, recipeType, recipe);

View File

@ -6,12 +6,12 @@ import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.cscorelib2.item.CustomItem; import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
import io.github.thebusybiscuit.cscorelib2.materials.MaterialCollections;
import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction; import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction;
import io.github.thebusybiscuit.slimefun4.core.handlers.BlockPlaceHandler; import io.github.thebusybiscuit.slimefun4.core.handlers.BlockPlaceHandler;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.utils.ChatUtils; import io.github.thebusybiscuit.slimefun4.utils.ChatUtils;
import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils; import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils;
import io.github.thebusybiscuit.slimefun4.utils.ColoredMaterials;
import io.github.thebusybiscuit.slimefun4.utils.HeadTexture; import io.github.thebusybiscuit.slimefun4.utils.HeadTexture;
import io.github.thebusybiscuit.slimefun4.utils.NumberUtils; import io.github.thebusybiscuit.slimefun4.utils.NumberUtils;
import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Lists.RecipeType;
@ -51,7 +51,7 @@ abstract class AbstractCargoNode extends SlimefunItem {
}); });
new BlockMenuPreset(getID(), ChatUtils.removeColorCodes(item.getItemMeta().getDisplayName())) { new BlockMenuPreset(getId(), ChatUtils.removeColorCodes(item.getItemMeta().getDisplayName())) {
@Override @Override
public void init() { public void init() {
@ -100,7 +100,7 @@ abstract class AbstractCargoNode extends SlimefunItem {
menu.replaceExistingItem(slotCurrent, new CustomItem(HeadTexture.CHEST_TERMINAL.getAsItemStack(), "&bChannel ID: &3" + (channel + 1))); menu.replaceExistingItem(slotCurrent, new CustomItem(HeadTexture.CHEST_TERMINAL.getAsItemStack(), "&bChannel ID: &3" + (channel + 1)));
menu.addMenuClickHandler(slotCurrent, ChestMenuUtils.getEmptyClickHandler()); menu.addMenuClickHandler(slotCurrent, ChestMenuUtils.getEmptyClickHandler());
} else { } else {
menu.replaceExistingItem(slotCurrent, new CustomItem(MaterialCollections.getAllWoolColors().get(channel), "&bChannel ID: &3" + (channel + 1))); menu.replaceExistingItem(slotCurrent, new CustomItem(ColoredMaterials.WOOL.get(channel), "&bChannel ID: &3" + (channel + 1)));
menu.addMenuClickHandler(slotCurrent, ChestMenuUtils.getEmptyClickHandler()); menu.addMenuClickHandler(slotCurrent, ChestMenuUtils.getEmptyClickHandler());
} }

View File

@ -32,7 +32,7 @@ abstract class AbstractFilterNode extends AbstractCargoNode {
public AbstractFilterNode(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe, ItemStack recipeOutput) { public AbstractFilterNode(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe, ItemStack recipeOutput) {
super(category, item, recipeType, recipe, recipeOutput); super(category, item, recipeType, recipe, recipeOutput);
registerBlockHandler(getID(), (p, b, stack, reason) -> { registerBlockHandler(getId(), (p, b, stack, reason) -> {
BlockMenu inv = BlockStorage.getInventory(b); BlockMenu inv = BlockStorage.getInventory(b);
if (inv != null) { if (inv != null) {

View File

@ -1,5 +1,7 @@
package io.github.thebusybiscuit.slimefun4.implementation.items.cargo; package io.github.thebusybiscuit.slimefun4.implementation.items.cargo;
import javax.annotation.Nonnull;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
@ -18,9 +20,14 @@ public class CargoConnectorNode extends SimpleSlimefunItem<BlockUseHandler> {
super(category, item, recipeType, recipe, recipeOutput); super(category, item, recipeType, recipe, recipeOutput);
} }
@Nonnull
@Override @Override
public BlockUseHandler getItemHandler() { public BlockUseHandler getItemHandler() {
return e -> { return e -> {
if (!e.getClickedBlock().isPresent()) {
return;
}
Player p = e.getPlayer(); Player p = e.getPlayer();
Block b = e.getClickedBlock().get(); Block b = e.getClickedBlock().get();

View File

@ -24,7 +24,7 @@ public class CargoManager extends SlimefunItem {
public CargoManager(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { public CargoManager(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(category, item, recipeType, recipe); super(category, item, recipeType, recipe);
registerBlockHandler(getID(), (p, b, tool, reason) -> { registerBlockHandler(getId(), (p, b, tool, reason) -> {
SimpleHologram.remove(b); SimpleHologram.remove(b);
return true; return true;
}); });

View File

@ -35,7 +35,7 @@ public class ReactorAccessPort extends SlimefunItem {
public ReactorAccessPort(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { public ReactorAccessPort(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(category, item, recipeType, recipe); super(category, item, recipeType, recipe);
new BlockMenuPreset(getID(), "&2Reactor Access Port") { new BlockMenuPreset(getId(), "&2Reactor Access Port") {
@Override @Override
public void init() { public void init() {
@ -94,7 +94,7 @@ public class ReactorAccessPort extends SlimefunItem {
} }
}; };
registerBlockHandler(getID(), (p, b, tool, reason) -> { registerBlockHandler(getId(), (p, b, tool, reason) -> {
BlockMenu inv = BlockStorage.getInventory(b); BlockMenu inv = BlockStorage.getInventory(b);
if (inv != null) { if (inv != null) {

View File

@ -8,6 +8,7 @@ import java.util.Set;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.ParametersAreNonnullByDefault; import javax.annotation.ParametersAreNonnullByDefault;
import org.apache.commons.lang.Validate;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
@ -89,11 +90,12 @@ public abstract class AbstractEnergyProvider extends SlimefunItem implements Inv
} }
public void registerFuel(@Nonnull MachineFuel fuel) { public void registerFuel(@Nonnull MachineFuel fuel) {
Validate.notNull(fuel, "Machine Fuel cannot be null!");
fuelTypes.add(fuel); fuelTypes.add(fuel);
} }
@Nonnull @Nonnull
public Set<MachineFuel> getFuelTypes() { public Set<MachineFuel> getFuelTypes2() {
return fuelTypes; return fuelTypes;
} }

View File

@ -0,0 +1,64 @@
package io.github.thebusybiscuit.slimefun4.implementation.items.electric;
import javax.annotation.Nonnull;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.cscorelib2.chat.ChatColors;
import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetComponent;
import io.github.thebusybiscuit.slimefun4.core.handlers.BlockUseHandler;
import io.github.thebusybiscuit.slimefun4.core.networks.energy.EnergyNet;
import io.github.thebusybiscuit.slimefun4.core.networks.energy.EnergyNetComponentType;
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
/**
* This {@link EnergyNetComponent} is a connector for the {@link EnergyNet} networks.
* They work similar to {@link Capacitor capacitors}.
*
* @author Linox
*
* @see EnergyNet
* @see EnergyNetComponent
*
*/
public class EnergyConnector extends SimpleSlimefunItem<BlockUseHandler> implements EnergyNetComponent {
public EnergyConnector(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe, ItemStack recipeOutput) {
super(category, item, recipeType, recipe, recipeOutput);
}
@Nonnull
@Override
public BlockUseHandler getItemHandler() {
return e -> {
if (!e.getClickedBlock().isPresent()) {
return;
}
Player p = e.getPlayer();
Block b = e.getClickedBlock().get();
if (EnergyNet.getNetworkFromLocation(b.getLocation()) != null) {
p.sendMessage(ChatColors.color("&7Connected: " + "&2\u2714"));
} else {
p.sendMessage(ChatColors.color("&7Connected: " + "&4\u2718"));
}
};
}
@Nonnull
@Override
public EnergyNetComponentType getEnergyComponentType() {
return EnergyNetComponentType.CONNECTOR;
}
@Override
public int getCapacity() {
return 0;
}
}

View File

@ -34,7 +34,7 @@ public class EnergyRegulator extends SlimefunItem {
public EnergyRegulator(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { public EnergyRegulator(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(category, item, recipeType, recipe); super(category, item, recipeType, recipe);
SlimefunItem.registerBlockHandler(getID(), (p, b, stack, reason) -> { SlimefunItem.registerBlockHandler(getId(), (p, b, stack, reason) -> {
SimpleHologram.remove(b); SimpleHologram.remove(b);
return true; return true;
}); });

View File

@ -9,6 +9,7 @@ import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory; import org.bukkit.inventory.PlayerInventory;
import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting; import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting;
import io.github.thebusybiscuit.slimefun4.api.items.settings.DoubleRangeSetting;
import io.github.thebusybiscuit.slimefun4.core.attributes.Rechargeable; import io.github.thebusybiscuit.slimefun4.core.attributes.Rechargeable;
import io.github.thebusybiscuit.slimefun4.implementation.tasks.ArmorTask; import io.github.thebusybiscuit.slimefun4.implementation.tasks.ArmorTask;
import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Lists.RecipeType;
@ -40,7 +41,7 @@ public class SolarHelmet extends SlimefunItem {
throw new IllegalArgumentException("A Solar Helmet must have a positive charging level!"); throw new IllegalArgumentException("A Solar Helmet must have a positive charging level!");
} }
charge = new ItemSetting<>("charge-amount", defaultChargingLevel); charge = new DoubleRangeSetting("charge-amount", 0.01, defaultChargingLevel, Double.MAX_VALUE);
addItemSetting(charge); addItemSetting(charge);
} }

View File

@ -48,15 +48,12 @@ public abstract class BioGenerator extends AGenerator {
registerFuel(new MachineFuel(20, new ItemStack(Material.DRIED_KELP_BLOCK))); registerFuel(new MachineFuel(20, new ItemStack(Material.DRIED_KELP_BLOCK)));
registerFuel(new MachineFuel(1, new ItemStack(Material.SEAGRASS))); registerFuel(new MachineFuel(1, new ItemStack(Material.SEAGRASS)));
registerFuel(new MachineFuel(2, new ItemStack(Material.SEA_PICKLE))); registerFuel(new MachineFuel(2, new ItemStack(Material.SEA_PICKLE)));
registerFuel(new MachineFuel(1, new ItemStack(Material.BAMBOO)));
registerFuel(new MachineFuel(2, new ItemStack(Material.SWEET_BERRIES)));
if (SlimefunPlugin.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_14)) { // Small Flowers (formally just dandelions and poppies).
registerFuel(new MachineFuel(1, new ItemStack(Material.BAMBOO))); for (Material m : Tag.SMALL_FLOWERS.getValues()) {
registerFuel(new MachineFuel(2, new ItemStack(Material.SWEET_BERRIES))); registerFuel(new MachineFuel(1, new ItemStack(m)));
// Small Flowers (formally just dandelions and poppies).
for (Material m : Tag.SMALL_FLOWERS.getValues()) {
registerFuel(new MachineFuel(1, new ItemStack(m)));
}
} }
if (SlimefunPlugin.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_15)) { if (SlimefunPlugin.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_15)) {

View File

@ -74,7 +74,7 @@ public abstract class CoalGenerator extends AGenerator {
} }
// Signs // Signs
for (Material mat : Tag.SIGNS.getValues()) { for (Material mat : Tag.STANDING_SIGNS.getValues()) {
registerFuel(new MachineFuel(2, new ItemStack(mat))); registerFuel(new MachineFuel(2, new ItemStack(mat)));
} }
} }

View File

@ -62,7 +62,7 @@ public abstract class AbstractEntityAssembler<T extends Entity> extends SimpleSl
public AbstractEntityAssembler(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { public AbstractEntityAssembler(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(category, item, recipeType, recipe); super(category, item, recipeType, recipe);
new BlockMenuPreset(getID(), item.getImmutableMeta().getDisplayName().orElse("Entity Assembler")) { new BlockMenuPreset(getId(), item.getImmutableMeta().getDisplayName().orElse("Entity Assembler")) {
@Override @Override
public void init() { public void init() {
@ -117,7 +117,7 @@ public abstract class AbstractEntityAssembler<T extends Entity> extends SimpleSl
}; };
addItemHandler(onPlace()); addItemHandler(onPlace());
registerBlockHandler(getID(), (p, b, stack, reason) -> { registerBlockHandler(getId(), (p, b, stack, reason) -> {
if (reason == UnregisterReason.EXPLODE) { if (reason == UnregisterReason.EXPLODE) {
return false; return false;
} }

View File

@ -28,7 +28,7 @@ public abstract class AbstractGrowthAccelerator extends SlimefunItem implements
createPreset(this, this::constructMenu); createPreset(this, this::constructMenu);
registerBlockHandler(getID(), (p, b, tool, reason) -> { registerBlockHandler(getId(), (p, b, tool, reason) -> {
BlockMenu inv = BlockStorage.getInventory(b); BlockMenu inv = BlockStorage.getInventory(b);
if (inv != null) { if (inv != null) {

View File

@ -39,7 +39,7 @@ public class AutoBreeder extends SlimefunItem implements InventoryBlock, EnergyN
createPreset(this, this::constructMenu); createPreset(this, this::constructMenu);
registerBlockHandler(getID(), (p, b, tool, reason) -> { registerBlockHandler(getId(), (p, b, tool, reason) -> {
BlockMenu inv = BlockStorage.getInventory(b); BlockMenu inv = BlockStorage.getInventory(b);
if (inv != null) { if (inv != null) {

View File

@ -5,6 +5,8 @@ import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import javax.annotation.Nullable;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.enchantments.Enchantment; import org.bukkit.enchantments.Enchantment;
@ -144,18 +146,16 @@ public class AutoDisenchanter extends AContainer {
book.setItemMeta(meta); book.setItemMeta(meta);
} }
private boolean isDisenchantable(ItemStack item) { private boolean isDisenchantable(@Nullable ItemStack item) {
if (item == null) { if (item == null) {
return false; return false;
} } else if (item.getType() != Material.BOOK) {
// stops endless checks of getByItem for books // ^ This stops endless checks of getByItem for books
else if (item.getType() != Material.BOOK) {
SlimefunItem sfItem = SlimefunItem.getByItem(item); SlimefunItem sfItem = SlimefunItem.getByItem(item);
return sfItem == null || sfItem.isDisenchantable(); return sfItem == null || sfItem.isDisenchantable();
} else { } else {
return true; return true;
} }
} }
@Override @Override

View File

@ -36,6 +36,13 @@ import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset;
import me.mrCookieSlime.Slimefun.api.inventory.DirtyChestMenu; import me.mrCookieSlime.Slimefun.api.inventory.DirtyChestMenu;
import me.mrCookieSlime.Slimefun.api.item_transport.ItemTransportFlow; import me.mrCookieSlime.Slimefun.api.item_transport.ItemTransportFlow;
/**
* This class needs to be rewritten VERY BADLY.
* But we should focus on rewriting the recipe system first.
*
* @author TheBusyBiscuit
*
*/
public abstract class AutomatedCraftingChamber extends SlimefunItem implements InventoryBlock, EnergyNetComponent { public abstract class AutomatedCraftingChamber extends SlimefunItem implements InventoryBlock, EnergyNetComponent {
private final int[] border = { 0, 1, 3, 4, 5, 7, 8, 13, 14, 15, 16, 17, 50, 51, 52, 53 }; private final int[] border = { 0, 1, 3, 4, 5, 7, 8, 13, 14, 15, 16, 17, 50, 51, 52, 53 };
@ -45,7 +52,7 @@ public abstract class AutomatedCraftingChamber extends SlimefunItem implements I
public AutomatedCraftingChamber(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { public AutomatedCraftingChamber(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(category, item, recipeType, recipe); super(category, item, recipeType, recipe);
new BlockMenuPreset(getID(), "&6Automated Crafting Chamber") { new BlockMenuPreset(getId(), "&6Automated Crafting Chamber") {
@Override @Override
public void init() { public void init() {
@ -113,7 +120,7 @@ public abstract class AutomatedCraftingChamber extends SlimefunItem implements I
}; };
addItemHandler(onPlace()); addItemHandler(onPlace());
registerBlockHandler(getID(), (p, b, stack, reason) -> { registerBlockHandler(getId(), (p, b, stack, reason) -> {
BlockMenu inv = BlockStorage.getInventory(b); BlockMenu inv = BlockStorage.getInventory(b);
if (inv != null) { if (inv != null) {
@ -233,11 +240,13 @@ public abstract class AutomatedCraftingChamber extends SlimefunItem implements I
} }
ItemStack item = menu.getItemInSlot(getInputSlots()[j]); ItemStack item = menu.getItemInSlot(getInputSlots()[j]);
if (item != null && item.getAmount() == 1) { if (item != null && item.getAmount() == 1) {
if (craftLast) if (craftLast) {
lastIteration = true; lastIteration = true;
else } else {
return ""; return "";
}
} }
builder.append(CustomItemSerializer.serialize(item, ItemFlag.MATERIAL, ItemFlag.ITEMMETA_DISPLAY_NAME, ItemFlag.ITEMMETA_LORE)); builder.append(CustomItemSerializer.serialize(item, ItemFlag.MATERIAL, ItemFlag.ITEMMETA_DISPLAY_NAME, ItemFlag.ITEMMETA_LORE));
@ -248,8 +257,9 @@ public abstract class AutomatedCraftingChamber extends SlimefunItem implements I
// we're only executing the last possible shaped recipe // we're only executing the last possible shaped recipe
// we don't want to allow this to be pressed instead of the default timer-based // we don't want to allow this to be pressed instead of the default timer-based
// execution to prevent abuse and auto clickers // execution to prevent abuse and auto clickers
if (craftLast && !lastIteration) if (craftLast && !lastIteration) {
return ""; return "";
}
return builder.toString(); return builder.toString();
} }

View File

@ -1,19 +1,14 @@
package io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines; package io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines;
import java.util.EnumSet;
import java.util.Set;
import org.bukkit.Material;
import org.bukkit.Particle; import org.bukkit.Particle;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.block.data.Ageable; import org.bukkit.block.data.Ageable;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils; import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
import io.github.thebusybiscuit.slimefun4.utils.itemstack.ItemStackWrapper; import io.github.thebusybiscuit.slimefun4.utils.itemstack.ItemStackWrapper;
import io.github.thebusybiscuit.slimefun4.utils.tags.SlimefunTag;
import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.api.BlockStorage; import me.mrCookieSlime.Slimefun.api.BlockStorage;
@ -22,24 +17,11 @@ import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu;
public abstract class CropGrowthAccelerator extends AbstractGrowthAccelerator { public abstract class CropGrowthAccelerator extends AbstractGrowthAccelerator {
private final Set<Material> crops = EnumSet.noneOf(Material.class);
// We wanna strip the Slimefun Item id here // We wanna strip the Slimefun Item id here
private static final ItemStack organicFertilizer = new ItemStackWrapper(SlimefunItems.FERTILIZER); private static final ItemStack organicFertilizer = new ItemStackWrapper(SlimefunItems.FERTILIZER);
public CropGrowthAccelerator(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { public CropGrowthAccelerator(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(category, item, recipeType, recipe); super(category, item, recipeType, recipe);
crops.add(Material.WHEAT);
crops.add(Material.POTATOES);
crops.add(Material.CARROTS);
crops.add(Material.NETHER_WART);
crops.add(Material.BEETROOTS);
crops.add(Material.COCOA);
if (SlimefunPlugin.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_14)) {
crops.add(Material.SWEET_BERRY_BUSH);
}
} }
public abstract int getEnergyConsumption(); public abstract int getEnergyConsumption();
@ -62,7 +44,7 @@ public abstract class CropGrowthAccelerator extends AbstractGrowthAccelerator {
for (int z = -getRadius(); z <= getRadius(); z++) { for (int z = -getRadius(); z <= getRadius(); z++) {
Block block = b.getRelative(x, 0, z); Block block = b.getRelative(x, 0, z);
if (crops.contains(block.getType()) && grow(b, inv, block)) { if (SlimefunTag.CROP_GROWTH_ACCELERATOR_BLOCKS.isTagged(block.getType()) && grow(b, inv, block)) {
return; return;
} }
} }

View File

@ -44,7 +44,7 @@ public abstract class ElectricSmeltery extends AContainer {
public ElectricSmeltery(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { public ElectricSmeltery(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(category, item, recipeType, recipe); super(category, item, recipeType, recipe);
new BlockMenuPreset(getID(), getItemName()) { new BlockMenuPreset(getId(), getItemName()) {
@Override @Override
public void init() { public void init() {
@ -99,7 +99,7 @@ public abstract class ElectricSmeltery extends AContainer {
} }
}; };
registerBlockHandler(getID(), (p, b, tool, reason) -> { registerBlockHandler(getId(), (p, b, tool, reason) -> {
BlockMenu inv = BlockStorage.getInventory(b); BlockMenu inv = BlockStorage.getInventory(b);
if (inv != null) { if (inv != null) {

View File

@ -4,7 +4,9 @@ import org.bukkit.Material;
import org.bukkit.Tag; import org.bukkit.Tag;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.cscorelib2.materials.MaterialCollections; import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.utils.tags.SlimefunTag;
import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AContainer; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AContainer;
@ -22,13 +24,18 @@ public abstract class ElectrifiedCrucible extends AContainer {
registerRecipe(8, new ItemStack[] { new ItemStack(Material.BUCKET), new ItemStack(Material.TERRACOTTA, 12) }, new ItemStack[] { new ItemStack(Material.LAVA_BUCKET) }); registerRecipe(8, new ItemStack[] { new ItemStack(Material.BUCKET), new ItemStack(Material.TERRACOTTA, 12) }, new ItemStack[] { new ItemStack(Material.LAVA_BUCKET) });
registerRecipe(10, new ItemStack[] { new ItemStack(Material.BUCKET), new ItemStack(Material.OBSIDIAN) }, new ItemStack[] { new ItemStack(Material.LAVA_BUCKET) }); registerRecipe(10, new ItemStack[] { new ItemStack(Material.BUCKET), new ItemStack(Material.OBSIDIAN) }, new ItemStack[] { new ItemStack(Material.LAVA_BUCKET) });
for (Material terracotta : MaterialCollections.getAllTerracottaColors().getAsArray()) { for (Material terracotta : SlimefunTag.TERRACOTTA.getValues()) {
registerRecipe(8, new ItemStack[] { new ItemStack(Material.BUCKET), new ItemStack(terracotta, 12) }, new ItemStack[] { new ItemStack(Material.LAVA_BUCKET) }); registerRecipe(8, new ItemStack[] { new ItemStack(Material.BUCKET), new ItemStack(terracotta, 12) }, new ItemStack[] { new ItemStack(Material.LAVA_BUCKET) });
} }
for (Material leaves : Tag.LEAVES.getValues()) { for (Material leaves : Tag.LEAVES.getValues()) {
registerRecipe(10, new ItemStack[] { new ItemStack(Material.BUCKET), new ItemStack(leaves, 16) }, new ItemStack[] { new ItemStack(Material.WATER_BUCKET) }); registerRecipe(10, new ItemStack[] { new ItemStack(Material.BUCKET), new ItemStack(leaves, 16) }, new ItemStack[] { new ItemStack(Material.WATER_BUCKET) });
} }
if (SlimefunPlugin.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_16)) {
registerRecipe(10, new ItemStack[] { new ItemStack(Material.BUCKET), new ItemStack(Material.BLACKSTONE, 8) }, new ItemStack[] { new ItemStack(Material.LAVA_BUCKET) });
registerRecipe(10, new ItemStack[] { new ItemStack(Material.BUCKET), new ItemStack(Material.BASALT, 12) }, new ItemStack[] { new ItemStack(Material.LAVA_BUCKET) });
}
} }
@Override @Override

View File

@ -54,7 +54,7 @@ public class FluidPump extends SimpleSlimefunItem<BlockTicker> implements Invent
createPreset(this, this::constructMenu); createPreset(this, this::constructMenu);
registerBlockHandler(getID(), (p, b, stack, reason) -> { registerBlockHandler(getId(), (p, b, stack, reason) -> {
BlockMenu inv = BlockStorage.getInventory(b); BlockMenu inv = BlockStorage.getInventory(b);
if (inv != null) { if (inv != null) {

View File

@ -3,10 +3,8 @@ package io.github.thebusybiscuit.slimefun4.implementation.items.electric.machine
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
import io.github.thebusybiscuit.slimefun4.core.attributes.RecipeDisplayItem; import io.github.thebusybiscuit.slimefun4.core.attributes.RecipeDisplayItem;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.items.misc.OrganicFertilizer; import io.github.thebusybiscuit.slimefun4.implementation.items.misc.OrganicFertilizer;
import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.Objects.Category;
@ -30,10 +28,7 @@ public abstract class FoodComposter extends AContainer implements RecipeDisplayI
registerRecipe(30, new ItemStack[] { SlimefunItems.APPLE_ORGANIC_FOOD }, new ItemStack[] { new SlimefunItemStack(SlimefunItems.APPLE_FERTILIZER, OrganicFertilizer.OUTPUT) }); registerRecipe(30, new ItemStack[] { SlimefunItems.APPLE_ORGANIC_FOOD }, new ItemStack[] { new SlimefunItemStack(SlimefunItems.APPLE_FERTILIZER, OrganicFertilizer.OUTPUT) });
registerRecipe(30, new ItemStack[] { SlimefunItems.KELP_ORGANIC_FOOD }, new ItemStack[] { new SlimefunItemStack(SlimefunItems.KELP_FERTILIZER, OrganicFertilizer.OUTPUT) }); registerRecipe(30, new ItemStack[] { SlimefunItems.KELP_ORGANIC_FOOD }, new ItemStack[] { new SlimefunItemStack(SlimefunItems.KELP_FERTILIZER, OrganicFertilizer.OUTPUT) });
registerRecipe(30, new ItemStack[] { SlimefunItems.COCOA_ORGANIC_FOOD }, new ItemStack[] { new SlimefunItemStack(SlimefunItems.COCOA_FERTILIZER, OrganicFertilizer.OUTPUT) }); registerRecipe(30, new ItemStack[] { SlimefunItems.COCOA_ORGANIC_FOOD }, new ItemStack[] { new SlimefunItemStack(SlimefunItems.COCOA_FERTILIZER, OrganicFertilizer.OUTPUT) });
registerRecipe(30, new ItemStack[] { SlimefunItems.SWEET_BERRIES_ORGANIC_FOOD }, new ItemStack[] { new SlimefunItemStack(SlimefunItems.SWEET_BERRIES_FERTILIZER, OrganicFertilizer.OUTPUT) });
if (SlimefunPlugin.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_14)) {
registerRecipe(30, new ItemStack[] { SlimefunItems.SWEET_BERRIES_ORGANIC_FOOD }, new ItemStack[] { new SlimefunItemStack(SlimefunItems.SWEET_BERRIES_FERTILIZER, OrganicFertilizer.OUTPUT) });
}
} }
@Override @Override

View File

@ -3,9 +3,7 @@ package io.github.thebusybiscuit.slimefun4.implementation.items.electric.machine
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.items.misc.OrganicFood; import io.github.thebusybiscuit.slimefun4.implementation.items.misc.OrganicFood;
import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.Objects.Category;
@ -29,10 +27,7 @@ public abstract class FoodFabricator extends AContainer {
registerRecipe(12, new ItemStack[] { SlimefunItems.TIN_CAN, new ItemStack(Material.APPLE) }, new ItemStack[] { new SlimefunItemStack(SlimefunItems.APPLE_ORGANIC_FOOD, OrganicFood.OUTPUT) }); registerRecipe(12, new ItemStack[] { SlimefunItems.TIN_CAN, new ItemStack(Material.APPLE) }, new ItemStack[] { new SlimefunItemStack(SlimefunItems.APPLE_ORGANIC_FOOD, OrganicFood.OUTPUT) });
registerRecipe(12, new ItemStack[] { SlimefunItems.TIN_CAN, new ItemStack(Material.DRIED_KELP) }, new ItemStack[] { new SlimefunItemStack(SlimefunItems.KELP_ORGANIC_FOOD, OrganicFood.OUTPUT) }); registerRecipe(12, new ItemStack[] { SlimefunItems.TIN_CAN, new ItemStack(Material.DRIED_KELP) }, new ItemStack[] { new SlimefunItemStack(SlimefunItems.KELP_ORGANIC_FOOD, OrganicFood.OUTPUT) });
registerRecipe(12, new ItemStack[] { SlimefunItems.TIN_CAN, new ItemStack(Material.COCOA_BEANS) }, new ItemStack[] { new SlimefunItemStack(SlimefunItems.COCOA_ORGANIC_FOOD, OrganicFood.OUTPUT) }); registerRecipe(12, new ItemStack[] { SlimefunItems.TIN_CAN, new ItemStack(Material.COCOA_BEANS) }, new ItemStack[] { new SlimefunItemStack(SlimefunItems.COCOA_ORGANIC_FOOD, OrganicFood.OUTPUT) });
registerRecipe(12, new ItemStack[] { SlimefunItems.TIN_CAN, new ItemStack(Material.SWEET_BERRIES) }, new ItemStack[] { new SlimefunItemStack(SlimefunItems.SWEET_BERRIES_ORGANIC_FOOD, OrganicFood.OUTPUT) });
if (SlimefunPlugin.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_14)) {
registerRecipe(12, new ItemStack[] { SlimefunItems.TIN_CAN, new ItemStack(Material.SWEET_BERRIES) }, new ItemStack[] { new SlimefunItemStack(SlimefunItems.SWEET_BERRIES_ORGANIC_FOOD, OrganicFood.OUTPUT) });
}
} }
@Override @Override

View File

@ -28,7 +28,7 @@ public abstract class HeatedPressureChamber extends AContainer {
public HeatedPressureChamber(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { public HeatedPressureChamber(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(category, item, recipeType, recipe); super(category, item, recipeType, recipe);
new BlockMenuPreset(getID(), getItemName()) { new BlockMenuPreset(getId(), getItemName()) {
@Override @Override
public void init() { public void init() {

View File

@ -38,7 +38,7 @@ public class XPCollector extends SlimefunItem implements InventoryBlock, EnergyN
createPreset(this, this::constructMenu); createPreset(this, this::constructMenu);
addItemHandler(onPlace()); addItemHandler(onPlace());
registerBlockHandler(getID(), (p, b, stack, reason) -> { registerBlockHandler(getId(), (p, b, stack, reason) -> {
BlockMenu inv = BlockStorage.getInventory(b); BlockMenu inv = BlockStorage.getInventory(b);
if (inv != null) { if (inv != null) {

View File

@ -80,7 +80,7 @@ public abstract class Reactor extends AbstractEnergyProvider {
public Reactor(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { public Reactor(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(category, item, recipeType, recipe); super(category, item, recipeType, recipe);
new BlockMenuPreset(getID(), getInventoryTitle()) { new BlockMenuPreset(getId(), getInventoryTitle()) {
@Override @Override
public void init() { public void init() {
@ -107,7 +107,7 @@ public abstract class Reactor extends AbstractEnergyProvider {
} }
}; };
registerBlockHandler(getID(), (p, b, tool, reason) -> { registerBlockHandler(getId(), (p, b, tool, reason) -> {
BlockMenu inv = BlockStorage.getInventory(b); BlockMenu inv = BlockStorage.getInventory(b);
if (inv != null) { if (inv != null) {
@ -360,7 +360,7 @@ public abstract class Reactor extends AbstractEnergyProvider {
inv.replaceExistingItem(22, new CustomItem(Material.BLACK_STAINED_GLASS_PANE, " ")); inv.replaceExistingItem(22, new CustomItem(Material.BLACK_STAINED_GLASS_PANE, " "));
if (processing.get(l).getOutput() != null) { if (processing.get(l).getOutput() != null) {
inv.pushItem(processing.get(l).getOutput(), getOutputSlots()); inv.pushItem(processing.get(l).getOutput().clone(), getOutputSlots());
} }
if (accessPort != null) { if (accessPort != null) {

View File

@ -0,0 +1,41 @@
package io.github.thebusybiscuit.slimefun4.implementation.items.food;
import io.github.thebusybiscuit.slimefun4.core.handlers.ItemUseHandler;
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
import org.bukkit.block.Block;
import org.bukkit.inventory.ItemStack;
import javax.annotation.Nonnull;
import javax.annotation.ParametersAreNonnullByDefault;
import java.util.Optional;
/**
* This {@link SlimefunItem} can be obtained by crafting, it's
* used for various foods and recipes
*
* @author TheSilentPro
*/
public class HeavyCream extends SimpleSlimefunItem<ItemUseHandler> {
@ParametersAreNonnullByDefault
public HeavyCream(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe, ItemStack recipeOutput) {
super(category, item, recipeType, recipe, recipeOutput);
}
@Nonnull
@Override
public ItemUseHandler getItemHandler() {
return e -> {
Optional<Block> block = e.getClickedBlock();
if (!block.isPresent() || !block.get().getType().isInteractable()) {
e.cancel();
}
};
}
}

View File

@ -3,6 +3,7 @@ package io.github.thebusybiscuit.slimefun4.implementation.items.food;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting; import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting;
import io.github.thebusybiscuit.slimefun4.api.items.settings.IntRangeSetting;
import io.github.thebusybiscuit.slimefun4.core.handlers.ItemConsumptionHandler; import io.github.thebusybiscuit.slimefun4.core.handlers.ItemConsumptionHandler;
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem; import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Lists.RecipeType;
@ -20,7 +21,7 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
*/ */
public class MeatJerky extends SimpleSlimefunItem<ItemConsumptionHandler> { public class MeatJerky extends SimpleSlimefunItem<ItemConsumptionHandler> {
private final ItemSetting<Integer> saturation = new ItemSetting<>("saturation-level", 6); private final ItemSetting<Integer> saturation = new IntRangeSetting("saturation-level", 0, 6, Integer.MAX_VALUE);
public MeatJerky(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { public MeatJerky(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(category, item, recipeType, recipe); super(category, item, recipeType, recipe);

View File

@ -41,7 +41,7 @@ public abstract class GEOMiner extends AContainer implements RecipeDisplayItem {
super(category, item, recipeType, recipe); super(category, item, recipeType, recipe);
addItemHandler(onPlace()); addItemHandler(onPlace());
registerBlockHandler(getID(), (p, b, stack, reason) -> { registerBlockHandler(getId(), (p, b, stack, reason) -> {
SimpleHologram.remove(b); SimpleHologram.remove(b);
BlockMenu inv = BlockStorage.getInventory(b); BlockMenu inv = BlockStorage.getInventory(b);

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