diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/MinecraftVersion.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/MinecraftVersion.java
index 511df32ec3..4fc0160ac6 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/api/MinecraftVersion.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/MinecraftVersion.java
@@ -10,10 +10,10 @@
/**
* This enum holds all versions of Minecraft that we currently support.
- *
+ *
* @author TheBusyBiscuit
* @author Walshy
- *
+ *
* @see Slimefun
*
*/
@@ -47,7 +47,13 @@ public enum MinecraftVersion {
* This constant represents Minecraft (Java Edition) Version 1.20
* ("The Trails & Tales Update")
*/
- MINECRAFT_1_20(20, "1.20.x"),
+ MINECRAFT_1_20(20, 0, 4, "1.20.x"),
+
+ /**
+ * This constant represents Minecraft (Java Edition) Version 1.20.5
+ * ("The Armored Paws Update")
+ */
+ MINECRAFT_1_20_5(20, 5, "1.20.5+"),
/**
* This constant represents an exceptional state in which we were unable
@@ -64,12 +70,14 @@ public enum MinecraftVersion {
private final String name;
private final boolean virtual;
private final int majorVersion;
+ private final int minorVersion;
+ private final int maxMinorVersion;
/**
* This constructs a new {@link MinecraftVersion} with the given name.
* This constructor forces the {@link MinecraftVersion} to be real.
* It must be a real version of Minecraft.
- *
+ *
* @param majorVersion
* The major version of minecraft as an {@link Integer}
* @param name
@@ -78,6 +86,50 @@ public enum MinecraftVersion {
MinecraftVersion(int majorVersion, @Nonnull String name) {
this.name = name;
this.majorVersion = majorVersion;
+ this.minorVersion = -1;
+ this.maxMinorVersion = -1;
+ this.virtual = false;
+ }
+
+ /**
+ * This constructs a new {@link MinecraftVersion} with the given name.
+ * This constructor forces the {@link MinecraftVersion} to be real.
+ * It must be a real version of Minecraft.
+ *
+ * @param majorVersion
+ * The major (minor in semver, major in MC land) version of minecraft as an {@link Integer}
+ * @param minor
+ * The minor (patch in semver, minor in MC land) version of minecraft as an {@link Integer}
+ * @param name
+ * The display name of this {@link MinecraftVersion}
+ */
+ MinecraftVersion(int majorVersion, int minor, @Nonnull String name) {
+ this.name = name;
+ this.majorVersion = majorVersion;
+ this.minorVersion = minor;
+ this.maxMinorVersion = -1;
+ this.virtual = false;
+ }
+
+ /**
+ * This constructs a new {@link MinecraftVersion} with the given name.
+ * This constructor forces the {@link MinecraftVersion} to be real.
+ * It must be a real version of Minecraft.
+ *
+ * @param majorVersion
+ * The major (minor in semver, major in MC land) version of minecraft as an {@link Integer}
+ * @param minor
+ * The minor (patch in semver, minor in MC land) version of minecraft as an {@link Integer}
+ * @param maxMinorVersion
+ * The maximum minor (patch) version of minecraft this version represents
+ * @param name
+ * The display name of this {@link MinecraftVersion}
+ */
+ MinecraftVersion(int majorVersion, int minor, int maxMinorVersion, @Nonnull String name) {
+ this.name = name;
+ this.majorVersion = majorVersion;
+ this.minorVersion = minor;
+ this.maxMinorVersion = maxMinorVersion;
this.virtual = false;
}
@@ -85,7 +137,7 @@ public enum MinecraftVersion {
* This constructs a new {@link MinecraftVersion} with the given name.
* A virtual {@link MinecraftVersion} (unknown or unit test) is not an actual
* version of Minecraft but rather a state of the {@link Server} software.
- *
+ *
* @param name
* The display name of this {@link MinecraftVersion}
* @param virtual
@@ -94,12 +146,14 @@ public enum MinecraftVersion {
MinecraftVersion(@Nonnull String name, boolean virtual) {
this.name = name;
this.majorVersion = 0;
+ this.minorVersion = -1;
+ this.maxMinorVersion = -1;
this.virtual = virtual;
}
/**
* This returns the name of this {@link MinecraftVersion} in a readable format.
- *
+ *
* @return The name of this {@link MinecraftVersion}
*/
public @Nonnull String getName() {
@@ -112,7 +166,7 @@ public enum MinecraftVersion {
* a state of the {@link Server} software used.
* Virtual {@link MinecraftVersion MinecraftVersions} include "UNKNOWN" and
* "UNIT TEST".
- *
+ *
* @return Whether this {@link MinecraftVersion} is virtual or not
*/
public boolean isVirtual() {
@@ -127,25 +181,49 @@ public boolean isVirtual() {
* It is equivalent to the "major" version
*
* Example: {@literal "1.13"} returns {@literal 13}
- *
+ *
* @param minecraftVersion
* The {@link Integer} version to match
- *
+ *
* @return Whether this {@link MinecraftVersion} matches the specified version id
*/
public boolean isMinecraftVersion(int minecraftVersion) {
- return !isVirtual() && this.majorVersion == minecraftVersion;
+ return this.isMinecraftVersion(minecraftVersion, -1);
+ }
+
+ /**
+ * This tests if the given minecraft version matches with this
+ * {@link MinecraftVersion}.
+ *
+ * You can obtain the version number by doing {@link PaperLib#getMinecraftVersion()}.
+ * It is equivalent to the "major" version
+ * You can obtain the patch version by doing {@link PaperLib#getMinecraftPatchVersion()}.
+ * It is equivalent to the "minor" version
+ *
+ * Example: {@literal "1.13"} returns {@literal 13}
+ * Example: {@literal "1.13.2"} returns {@literal 13_2}
+ *
+ * @param minecraftVersion
+ * The {@link Integer} version to match
+ *
+ * @return Whether this {@link MinecraftVersion} matches the specified version id
+ */
+ public boolean isMinecraftVersion(int minecraftVersion, int patchVersion) {
+ return !isVirtual()
+ && this.majorVersion == minecraftVersion
+ && (this.minorVersion == -1 || this.minorVersion <= patchVersion)
+ && (this.maxMinorVersion == -1 || patchVersion <= this.maxMinorVersion);
}
/**
* This method checks whether this {@link MinecraftVersion} is newer or equal to
* the given {@link MinecraftVersion},
- *
+ *
* An unknown version will default to {@literal false}.
- *
+ *
* @param version
* The {@link MinecraftVersion} to compare
- *
+ *
* @return Whether this {@link MinecraftVersion} is newer or equal to the given {@link MinecraftVersion}
*/
public boolean isAtLeast(@Nonnull MinecraftVersion version) {
@@ -162,7 +240,7 @@ public boolean isAtLeast(@Nonnull MinecraftVersion version) {
* this will essentially always return true and result in a tautology.
* This is most definitely an oversight from us and should be fixed, therefore
* we will trigger an exception.
- *
+ *
* In order to not disrupt server operations, this exception is only thrown during
* unit tests since the oversight itself will be harmless.
*/
@@ -175,12 +253,12 @@ public boolean isAtLeast(@Nonnull MinecraftVersion version) {
/**
* This checks whether this {@link MinecraftVersion} is older than the specified {@link MinecraftVersion}.
- *
+ *
* An unknown version will default to {@literal true}.
- *
+ *
* @param version
* The {@link MinecraftVersion} to compare
- *
+ *
* @return Whether this {@link MinecraftVersion} is older than the given one
*/
public boolean isBefore(@Nonnull MinecraftVersion version) {
@@ -193,4 +271,24 @@ public boolean isBefore(@Nonnull MinecraftVersion version) {
return version.ordinal() > this.ordinal();
}
+ /**
+ * Checks whether this {@link MinecraftVersion} is older than the specified minecraft and patch versions
+ * @param minecraftVersion The minecraft version
+ * @param patchVersion The patch version
+ * @return True if this version is before, False if this version is virtual or otherwise.
+ */
+ public boolean isBefore(int minecraftVersion, int patchVersion) {
+ // unit tests or whatever
+ if (isVirtual()) {
+ return false;
+ }
+
+ // major version mismatch
+ if (this.majorVersion != minecraftVersion) {
+ return this.majorVersion < minecraftVersion;
+ }
+
+ return this.minorVersion == -1 ? patchVersion > 0 : this.minorVersion < patchVersion;
+ }
+
}
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/RadiationDamageEvent.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/RadiationDamageEvent.java
new file mode 100644
index 0000000000..b3ef284e75
--- /dev/null
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/RadiationDamageEvent.java
@@ -0,0 +1,69 @@
+package io.github.thebusybiscuit.slimefun4.api.events;
+
+import javax.annotation.Nonnull;
+
+import org.bukkit.entity.Player;
+import org.bukkit.event.Cancellable;
+import org.bukkit.event.Event;
+import org.bukkit.event.HandlerList;
+
+/**
+ * The {@link RadiationDamageEvent} is called when a player takes radiation damage.
+ *
+ * @author HoosierTransfer
+ */
+public class RadiationDamageEvent extends Event implements Cancellable {
+ private static final HandlerList handlers = new HandlerList();
+
+ private final Player player;
+ private final int exposure;
+ private boolean cancelled;
+
+ /**
+ * This constructs a new {@link RadiationDamageEvent}.
+ *
+ * @param player The {@link Player} who took radiation damage
+ * @param exposure The amount of radiation exposure
+ */
+ public RadiationDamageEvent(@Nonnull Player player, int exposure) {
+ this.player = player;
+ this.exposure = exposure;
+ }
+
+ /**
+ * This returns the {@link Player} who took radiation damage.
+ *
+ * @return The {@link Player} who took radiation damage
+ */
+ public @Nonnull Player getPlayer() {
+ return player;
+ }
+
+ /**
+ * This returns the amount of radiation exposure.
+ *
+ * @return The amount of radiation exposure
+ */
+ public int getExposure() {
+ return exposure;
+ }
+
+ @Override
+ public boolean isCancelled() {
+ return cancelled;
+ }
+
+ @Override
+ public void setCancelled(boolean cancelled) {
+ this.cancelled = cancelled;
+ }
+
+ public static @Nonnull HandlerList getHandlerList() {
+ return handlers;
+ }
+
+ @Override
+ public @Nonnull HandlerList getHandlers() {
+ return getHandlerList();
+ }
+}
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/TalismanActivateEvent.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/TalismanActivateEvent.java
index 775691a0a6..b8515bed47 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/TalismanActivateEvent.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/TalismanActivateEvent.java
@@ -93,4 +93,4 @@ public void setCancelled(boolean cancel) {
public static @Nonnull HandlerList getHandlerList() {
return handlers;
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/gps/TeleportationManager.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/gps/TeleportationManager.java
index 19646ed4c0..6f65962024 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/api/gps/TeleportationManager.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/gps/TeleportationManager.java
@@ -16,7 +16,6 @@
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.potion.PotionEffect;
-import org.bukkit.potion.PotionEffectType;
import io.github.bakedlibs.dough.common.ChatColors;
import io.github.bakedlibs.dough.items.CustomItemStack;
@@ -27,6 +26,7 @@
import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils;
import io.github.thebusybiscuit.slimefun4.utils.HeadTexture;
import io.github.thebusybiscuit.slimefun4.utils.NumberUtils;
+import io.github.thebusybiscuit.slimefun4.utils.compatibility.VersionedPotionEffectType;
import io.papermc.lib.PaperLib;
import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu;
@@ -220,7 +220,7 @@ private void onTeleport(Player p, Location destination, boolean success, boolean
if (success) {
// Apply Resistance Effect, if enabled
if (resistance) {
- p.addPotionEffect(new PotionEffect(PotionEffectType.DAMAGE_RESISTANCE, 600, 20));
+ p.addPotionEffect(new PotionEffect(VersionedPotionEffectType.RESISTANCE, 600, 20));
Slimefun.getLocalization().sendMessage(p, "machines.TELEPORTER.invulnerability");
}
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/items/ItemGroup.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/items/ItemGroup.java
index 0f70a46e6e..81b8f331f6 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/api/items/ItemGroup.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/items/ItemGroup.java
@@ -25,6 +25,7 @@
import io.github.thebusybiscuit.slimefun4.api.items.groups.SeasonalItemGroup;
import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuide;
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
+import io.github.thebusybiscuit.slimefun4.utils.compatibility.VersionedItemFlag;
/**
* Represents an item group, which structure
@@ -85,7 +86,7 @@ public ItemGroup(NamespacedKey key, ItemStack item, int tier) {
ItemMeta meta = item.getItemMeta();
meta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES);
meta.addItemFlags(ItemFlag.HIDE_ENCHANTS);
- meta.addItemFlags(ItemFlag.HIDE_POTION_EFFECTS);
+ meta.addItemFlags(VersionedItemFlag.HIDE_ADDITIONAL_TOOLTIP);
this.item.setItemMeta(meta);
this.tier = tier;
}
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/items/SlimefunItem.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/items/SlimefunItem.java
index 6400d8b925..ea3775037c 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/api/items/SlimefunItem.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/items/SlimefunItem.java
@@ -160,6 +160,21 @@ public SlimefunItem(ItemGroup itemGroup, SlimefunItemStack item, RecipeType reci
this.recipeOutput = recipeOutput;
}
+ /**
+ * This creates a new {@link SlimefunItem} from the given arguments.
+ *
+ * @param itemGroup
+ * The {@link ItemGroup} this {@link SlimefunItem} belongs
+ * to
+ * @param item
+ * The {@link SlimefunItemStack} that describes the visual
+ * features of our {@link SlimefunItem}
+ */
+ @ParametersAreNonnullByDefault
+ public SlimefunItem(ItemGroup itemGroup, SlimefunItemStack item) {
+ this(itemGroup, item, RecipeType.NULL, new ItemStack[] {});
+ }
+
// Previously deprecated constructor, now only for internal purposes
@ParametersAreNonnullByDefault
protected SlimefunItem(ItemGroup itemGroup, ItemStack item, String id, RecipeType recipeType, ItemStack[] recipe) {
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/items/SlimefunItemStack.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/items/SlimefunItemStack.java
index 5604cdcfa8..611e85df6d 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/api/items/SlimefunItemStack.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/items/SlimefunItemStack.java
@@ -15,7 +15,6 @@
import org.bukkit.ChatColor;
import org.bukkit.Color;
import org.bukkit.Material;
-import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.LeatherArmorMeta;
@@ -32,6 +31,7 @@
import io.github.thebusybiscuit.slimefun4.api.exceptions.WrongItemStackException;
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
import io.github.thebusybiscuit.slimefun4.utils.HeadTexture;
+import io.github.thebusybiscuit.slimefun4.utils.compatibility.VersionedItemFlag;
/**
* The {@link SlimefunItemStack} functions as the base for any
@@ -159,7 +159,7 @@ public SlimefunItemStack(@Nonnull String id, @Nonnull Color color, @Nonnull Poti
potionMeta.addCustomEffect(effect, true);
if (effect.getType().equals(PotionEffectType.SATURATION)) {
- im.addItemFlags(ItemFlag.HIDE_POTION_EFFECTS);
+ im.addItemFlags(VersionedItemFlag.HIDE_ADDITIONAL_TOOLTIP);
}
}
});
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/network/NetworkVisualizer.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/network/NetworkVisualizer.java
index 14ab69c85f..256442972a 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/api/network/NetworkVisualizer.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/network/NetworkVisualizer.java
@@ -5,9 +5,10 @@
import org.apache.commons.lang.Validate;
import org.bukkit.Color;
import org.bukkit.Location;
-import org.bukkit.Particle;
import org.bukkit.Particle.DustOptions;
+import io.github.thebusybiscuit.slimefun4.utils.compatibility.VersionedParticle;
+
/**
* This class represents the visualizer task of a given {@link Network}.
*
@@ -58,7 +59,7 @@ public void run() {
* The {@link Location} of our node
*/
private void spawnParticles(@Nonnull Location l) {
- l.getWorld().spawnParticle(Particle.REDSTONE, l.getX() + 0.5, l.getY() + 0.5, l.getZ() + 0.5, 1, 0, 0, 0, 1, particleOptions);
+ l.getWorld().spawnParticle(VersionedParticle.DUST, l.getX() + 0.5, l.getY() + 0.5, l.getZ() + 0.5, 1, 0, 0, 0, 1, particleOptions);
}
}
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/player/PlayerProfile.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/player/PlayerProfile.java
index 96290f4849..8dfc7414f8 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/api/player/PlayerProfile.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/player/PlayerProfile.java
@@ -3,12 +3,13 @@
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import java.util.Optional;
import java.util.OptionalInt;
import java.util.Set;
import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Consumer;
-import java.util.stream.IntStream;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@@ -35,6 +36,8 @@
import io.github.thebusybiscuit.slimefun4.api.researches.Research;
import io.github.thebusybiscuit.slimefun4.core.attributes.ProtectionType;
import io.github.thebusybiscuit.slimefun4.core.attributes.ProtectiveArmor;
+import io.github.thebusybiscuit.slimefun4.core.debug.Debug;
+import io.github.thebusybiscuit.slimefun4.core.debug.TestCase;
import io.github.thebusybiscuit.slimefun4.core.guide.GuideHistory;
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
import io.github.thebusybiscuit.slimefun4.implementation.items.armor.SlimefunArmorPiece;
@@ -54,6 +57,8 @@
*/
public class PlayerProfile {
+ private static final Map loading = new ConcurrentHashMap<>();
+
private final UUID ownerId;
private final String name;
@@ -237,6 +242,7 @@ public void removeWaypoint(@Nonnull Waypoint waypoint) {
* The profile can then be removed from RAM.
*/
public final void markForDeletion() {
+ Debug.log(TestCase.PLAYER_PROFILE_DATA, "Marking {} ({}) profile for deletion", name, ownerId);
markedForDeletion = true;
}
@@ -244,6 +250,7 @@ public final void markForDeletion() {
* Call this method if this Profile has unsaved changes.
*/
public final void markDirty() {
+ Debug.log(TestCase.PLAYER_PROFILE_DATA, "Marking {} ({}) profile as dirty", name, ownerId);
dirty = true;
}
@@ -358,22 +365,47 @@ public static boolean fromUUID(@Nonnull UUID uuid, @Nonnull Consumer callback) {
Validate.notNull(p, "Cannot get a PlayerProfile for: null!");
-
UUID uuid = p.getUniqueId();
+
+ Debug.log(TestCase.PLAYER_PROFILE_DATA, "Getting PlayerProfile for {}", uuid);
+
PlayerProfile profile = Slimefun.getRegistry().getPlayerProfiles().get(uuid);
if (profile != null) {
+ Debug.log(TestCase.PLAYER_PROFILE_DATA, "PlayerProfile for {} was already loaded", uuid);
callback.accept(profile);
return true;
}
- Bukkit.getScheduler().runTaskAsynchronously(Slimefun.instance(), () -> {
+ // If we're already loading, we don't want to spin up a whole new thread and load the profile again/more
+ // This can very easily cause CPU, memory and thread exhaustion if the profile is large
+ // See #4011, #4116
+ if (loading.containsKey(uuid)) {
+ Debug.log(TestCase.PLAYER_PROFILE_DATA, "Attempted to get PlayerProfile ({}) while loading", uuid);
+
+ // We can't easily consume the callback so we will throw it away in this case
+ // This will mean that if a user has attempted to do an action like open a block while
+ // their profile is still loading. Instead of it opening after a second or whatever when the
+ // profile is loaded, they will have to explicitly re-click the block/item/etc.
+ // This isn't the best but I think it's totally reasonable.
+ return false;
+ }
+
+ loading.put(uuid, true);
+ Slimefun.getThreadService().newThread(Slimefun.instance(), "PlayerProfile#get(" + uuid + ")", () -> {
PlayerData data = Slimefun.getPlayerStorage().loadPlayerData(p.getUniqueId());
AsyncProfileLoadEvent event = new AsyncProfileLoadEvent(new PlayerProfile(p, data));
Bukkit.getPluginManager().callEvent(event);
Slimefun.getRegistry().getPlayerProfiles().put(uuid, event.getProfile());
+
+ // Make sure we call this after we put the PlayerProfile into the registry.
+ // Otherwise, we end up with a race condition where the profile is not in the map just _yet_
+ // but the loading flag is gone and we can end up loading it a second time (and thus can dupe items)
+ // Fixes https://github.com/Slimefun/Slimefun4/issues/4130
+ loading.remove(uuid);
+
callback.accept(event.getProfile());
});
@@ -391,14 +423,32 @@ public static boolean get(@Nonnull OfflinePlayer p, @Nonnull Consumer {
- PlayerData data = Slimefun.getPlayerStorage().loadPlayerData(p.getUniqueId());
+ Slimefun.getThreadService().newThread(Slimefun.instance(), "PlayerProfile#request(" + uuid + ")", () -> {
+ PlayerData data = Slimefun.getPlayerStorage().loadPlayerData(uuid);
PlayerProfile pp = new PlayerProfile(p, data);
- Slimefun.getRegistry().getPlayerProfiles().put(p.getUniqueId(), pp);
+ Slimefun.getRegistry().getPlayerProfiles().put(uuid, pp);
+
+ // Make sure we call this after we put the PlayerProfile into the registry.
+ // Otherwise, we end up with a race condition where the profile is not in the map just _yet_
+ // but the loading flag is gone and we can end up loading it a second time (and thus can dupe items)
+ // Fixes https://github.com/Slimefun/Slimefun4/issues/4130
+ loading.remove(uuid);
});
return false;
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/DamageableItem.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/DamageableItem.java
index 05694f3e64..74f4a5ef88 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/DamageableItem.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/DamageableItem.java
@@ -13,6 +13,7 @@
import io.github.bakedlibs.dough.config.Config;
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem;
import io.github.thebusybiscuit.slimefun4.utils.UnbreakingAlgorithm;
+import io.github.thebusybiscuit.slimefun4.utils.compatibility.VersionedEnchantment;
/**
* This interface, when attached to a {@link SlimefunItem}, provides an easy method for damaging
@@ -51,7 +52,7 @@ public interface DamageableItem extends ItemAttribute {
*/
default void damageItem(@Nonnull Player p, @Nullable ItemStack item) {
if (isDamageable() && item != null && !item.getType().isAir() && item.getAmount() > 0) {
- int unbreakingLevel = item.getEnchantmentLevel(Enchantment.DURABILITY);
+ int unbreakingLevel = item.getEnchantmentLevel(VersionedEnchantment.UNBREAKING);
if (evaluateUnbreakingEnchantment(unbreakingLevel)) {
return;
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/RadiationSymptom.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/RadiationSymptom.java
index 2c703de40b..154b48efc4 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/RadiationSymptom.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/RadiationSymptom.java
@@ -10,6 +10,7 @@
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
import io.github.thebusybiscuit.slimefun4.utils.RadiationUtils;
+import io.github.thebusybiscuit.slimefun4.utils.compatibility.VersionedPotionEffectType;
/**
* An enum of potential radiation symptoms.
@@ -25,11 +26,11 @@
*/
public enum RadiationSymptom {
- SLOW(10, PotionEffectType.SLOW, 3),
+ SLOW(10, VersionedPotionEffectType.SLOWNESS, 3),
WITHER_LOW(25, PotionEffectType.WITHER, 0),
BLINDNESS(50, PotionEffectType.BLINDNESS, 4),
WITHER_HIGH(75, PotionEffectType.WITHER, 3),
- IMMINENT_DEATH(100, PotionEffectType.HARM, 49);
+ IMMINENT_DEATH(100, VersionedPotionEffectType.INSTANT_DAMAGE, 49);
private final int minExposure;
private final PotionEffect potionEffect;
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/SlimefunTabCompleter.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/SlimefunTabCompleter.java
index 07ca70bf0c..50a665f308 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/SlimefunTabCompleter.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/SlimefunTabCompleter.java
@@ -16,6 +16,7 @@
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem;
import io.github.thebusybiscuit.slimefun4.api.researches.Research;
+import io.github.thebusybiscuit.slimefun4.core.debug.TestCase;
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
class SlimefunTabCompleter implements TabCompleter {
@@ -33,6 +34,13 @@ public SlimefunTabCompleter(@Nonnull SlimefunCommand command) {
public List onTabComplete(CommandSender sender, Command cmd, String label, String[] args) {
if (args.length == 1) {
return createReturnList(command.getSubCommandNames(), args[0]);
+ } else if (args.length == 2) {
+ if (args[0].equalsIgnoreCase("debug")) {
+ return createReturnList(TestCase.VALUES_LIST, args[1]);
+ } else {
+ // Returning null will make it fallback to the default arguments (all online players)
+ return null;
+ }
} else if (args.length == 3) {
if (args[0].equalsIgnoreCase("give")) {
return createReturnList(getSlimefunItems(), args[2]);
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/VersionsCommand.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/VersionsCommand.java
index da4b8d4e06..34ff1f4a20 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/VersionsCommand.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/VersionsCommand.java
@@ -65,11 +65,25 @@ public void onExecute(@Nonnull CommandSender sender, @Nonnull String[] args) {
.append(serverSoftware)
.color(ChatColor.GREEN)
.append(" " + Bukkit.getVersion() + '\n')
- .color(ChatColor.DARK_GREEN)
+ .color(ChatColor.DARK_GREEN);
+
+ builder
.append("Slimefun ")
.color(ChatColor.GREEN)
- .append(Slimefun.getVersion() + '\n')
+ .append(Slimefun.getVersion())
.color(ChatColor.DARK_GREEN);
+ if (!Slimefun.getUpdater().isLatestVersion()) {
+ builder
+ .append(" (").color(ChatColor.GRAY)
+ .append("Update available").color(ChatColor.RED).event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text(
+ "Your Slimefun version is out of date!\n" +
+ "Please update to get the latest bug fixes and performance improvements.\n" +
+ "Please do not report any bugs without updating first."
+ )))
+ .append(")").color(ChatColor.GRAY);
+ }
+
+ builder.append("\n").event((HoverEvent) null);
// @formatter:on
if (Slimefun.getMetricsService().getVersion() != null) {
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/debug/TestCase.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/debug/TestCase.java
index 00b3bbf70c..e41ecddc42 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/debug/TestCase.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/debug/TestCase.java
@@ -1,9 +1,13 @@
package io.github.thebusybiscuit.slimefun4.core.debug;
+import java.util.Arrays;
+import java.util.List;
import java.util.Locale;
import javax.annotation.Nonnull;
+import io.github.thebusybiscuit.slimefun4.core.services.AnalyticsService;
+
/**
* Test cases in Slimefun. These are very useful for debugging why behavior is happening.
* Server owners can enable these with {@code /sf debug }
@@ -17,7 +21,20 @@ public enum TestCase {
* being checked and why it is comparing IDs or meta.
* This is helpful for us to check into why input nodes are taking a while for servers.
*/
- CARGO_INPUT_TESTING;
+ CARGO_INPUT_TESTING,
+
+ /**
+ * Debug information regarding player profile loading, saving and handling.
+ * This is an area we're currently changing quite a bit and this will help ensure we're doing it safely
+ */
+ PLAYER_PROFILE_DATA,
+
+ /**
+ * Debug information regarding our {@link AnalyticsService}.
+ */
+ ANALYTICS;
+
+ public static final List VALUES_LIST = Arrays.stream(values()).map(TestCase::toString).toList();
TestCase() {}
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/options/FireworksOption.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/options/FireworksOption.java
index 07b757018a..64f48a0656 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/options/FireworksOption.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/options/FireworksOption.java
@@ -1,5 +1,6 @@
package io.github.thebusybiscuit.slimefun4.core.guide.options;
+import java.util.List;
import java.util.Optional;
import org.bukkit.Material;
@@ -31,7 +32,13 @@ public Optional getDisplayItem(Player p, ItemStack guide) {
if (registry.isResearchingEnabled() && registry.isResearchFireworkEnabled()) {
boolean enabled = getSelectedOption(p, guide).orElse(true);
- ItemStack item = new CustomItemStack(Material.FIREWORK_ROCKET, "&bFireworks: &" + (enabled ? "aYes" : "4No"), "", "&7You can now toggle whether you", "&7will be presented with a big firework", "&7upon researching an item.", "", "&7\u21E8 &eClick to " + (enabled ? "disable" : "enable") + " your fireworks");
+
+ String optionState = enabled ? "enabled" : "disabled";
+ List lore = Slimefun.getLocalization().getMessages(p, "guide.options.fireworks." + optionState + ".text");
+ lore.add("");
+ lore.add("&7\u21E8 " + Slimefun.getLocalization().getMessage(p, "guide.options.fireworks." + optionState + ".click"));
+
+ ItemStack item = new CustomItemStack(Material.FIREWORK_ROCKET, lore);
return Optional.of(item);
} else {
return Optional.empty();
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/options/GuideModeOption.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/options/GuideModeOption.java
index f86694211d..92ede97bc9 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/options/GuideModeOption.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/options/GuideModeOption.java
@@ -56,14 +56,15 @@ public Optional getDisplayItem(Player p, ItemStack guide) {
}
ItemMeta meta = item.getItemMeta();
- meta.setDisplayName(ChatColor.GRAY + "Slimefun Guide Type: " + ChatColor.YELLOW + ChatUtils.humanize(selectedMode.name()));
+ meta.setDisplayName(ChatColor.GRAY + Slimefun.getLocalization().getMessage(p, "guide.modes.selected") +
+ ChatColor.YELLOW + Slimefun.getLocalization().getMessage(p, "guide.modes." + selectedMode.name()));
List lore = new ArrayList<>();
lore.add("");
- lore.add((selectedMode == SlimefunGuideMode.SURVIVAL_MODE ? ChatColor.GREEN : ChatColor.GRAY) + "Survival Mode");
- lore.add((selectedMode == SlimefunGuideMode.CHEAT_MODE ? ChatColor.GREEN : ChatColor.GRAY) + "Cheat Sheet");
+ lore.add((selectedMode == SlimefunGuideMode.SURVIVAL_MODE ? ChatColor.GREEN : ChatColor.GRAY) + Slimefun.getLocalization().getMessage(p, "guide.modes.SURVIVAL_MODE"));
+ lore.add((selectedMode == SlimefunGuideMode.CHEAT_MODE ? ChatColor.GREEN : ChatColor.GRAY) + Slimefun.getLocalization().getMessage(p, "guide.modes.CHEAT_MODE"));
lore.add("");
- lore.add(ChatColor.GRAY + "\u21E8 " + ChatColor.YELLOW + "Click to change the type");
+ lore.add(ChatColor.GRAY + "\u21E8 " + ChatColor.YELLOW + Slimefun.getLocalization().getMessage(p, "guide.modes.change"));
meta.setLore(lore);
item.setItemMeta(meta);
@@ -114,4 +115,4 @@ public void setSelectedOption(Player p, ItemStack guide, SlimefunGuideMode value
guide.setItemMeta(SlimefunGuide.getItem(value).getItemMeta());
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/AnalyticsService.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/AnalyticsService.java
new file mode 100644
index 0000000000..b0afd40657
--- /dev/null
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/AnalyticsService.java
@@ -0,0 +1,158 @@
+package io.github.thebusybiscuit.slimefun4.core.services;
+
+import java.net.URI;
+import java.net.http.HttpClient;
+import java.net.http.HttpRequest;
+import java.net.http.HttpResponse;
+import java.util.concurrent.TimeUnit;
+
+import javax.annotation.Nonnull;
+import javax.annotation.ParametersAreNonnullByDefault;
+
+import org.bukkit.plugin.Plugin;
+import org.bukkit.plugin.java.JavaPlugin;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonObject;
+
+import io.github.thebusybiscuit.slimefun4.core.debug.Debug;
+import io.github.thebusybiscuit.slimefun4.core.debug.TestCase;
+import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
+
+/**
+ * This class represents an analytics service that sends data.
+ * This data is used to analyse performance of this {@link Plugin}.
+ *
+ * You can find more info in the README file of this Project on GitHub.
+ *
+ * @author WalshyDev
+ */
+public class AnalyticsService {
+
+ private static final int VERSION = 1;
+ private static final String API_URL = "https://analytics.slimefun.dev/ingest";
+
+ private final JavaPlugin plugin;
+ private final HttpClient client = HttpClient.newHttpClient();
+
+ private boolean enabled;
+
+ public AnalyticsService(JavaPlugin plugin) {
+ this.plugin = plugin;
+ }
+
+ public void start() {
+ this.enabled = Slimefun.getCfg().getBoolean("metrics.analytics");
+
+ if (enabled) {
+ plugin.getLogger().info("Enabled Analytics Service");
+
+ // Send the timings data every minute
+ Slimefun.getThreadService().newScheduledThread(
+ plugin,
+ "AnalyticsService - Timings",
+ sendTimingsAnalytics(),
+ 1,
+ 1,
+ TimeUnit.MINUTES
+ );
+ }
+ }
+
+ // We'll send some timing data every minute.
+ // To date, we collect the tick interval, the avg timing per tick and avg timing per machine
+ @Nonnull
+ private Runnable sendTimingsAnalytics() {
+ return () -> {
+ double tickInterval = Slimefun.getTickerTask().getTickRate();
+ // This is currently used by bStats in a ranged way, we'll move this
+ double totalTimings = Slimefun.getProfiler().getAndResetAverageNanosecondTimings();
+ double avgPerMachine = Slimefun.getProfiler().getAverageTimingsPerMachine();
+
+ if (totalTimings == 0 || avgPerMachine == 0) {
+ Debug.log(TestCase.ANALYTICS, "Ignoring analytics data for server_timings as no data was found"
+ + " - total: " + totalTimings + ", avg: " + avgPerMachine);
+ // Ignore if no data
+ return;
+ }
+
+ send("server_timings", new double[]{
+ // double1 is schema version
+ tickInterval, // double2
+ totalTimings, // double3
+ avgPerMachine // double4
+ }, null);
+ };
+ }
+
+ public void recordPlayerProfileDataTime(@Nonnull String backend, boolean load, long nanoseconds) {
+ send(
+ "player_profile_data_load_time",
+ new double[]{
+ // double1 is schema version
+ nanoseconds, // double2
+ load ? 1 : 0 // double3 - 1 if load, 0 if save
+ },
+ new String[]{
+ // blob1 is version
+ backend // blob2
+ }
+ );
+ }
+
+ // Important: Keep the order of these doubles and blobs the same unless you increment the version number
+ // If a value is no longer used, just send null or replace it with a new value - don't shift the order
+ @ParametersAreNonnullByDefault
+ private void send(String id, double[] doubles, String[] blobs) {
+ // If not enabled or not official build (e.g. local build) or a unit test, just ignore.
+ if (
+ !enabled
+ || !Slimefun.getUpdater().getBranch().isOfficial()
+ || Slimefun.instance().isUnitTest()
+ ) return;
+
+ JsonObject object = new JsonObject();
+ // Up to 1 index
+ JsonArray indexes = new JsonArray();
+ indexes.add(id);
+ object.add("indexes", indexes);
+
+ // Up to 20 doubles (including the version)
+ JsonArray doublesArray = new JsonArray();
+ doublesArray.add(VERSION);
+ if (doubles != null) {
+ for (double d : doubles) {
+ doublesArray.add(d);
+ }
+ }
+ object.add("doubles", doublesArray);
+
+ // Up to 20 blobs (including the version)
+ JsonArray blobsArray = new JsonArray();
+ blobsArray.add(Slimefun.getVersion());
+ if (blobs != null) {
+ for (String s : blobs) {
+ blobsArray.add(s);
+ }
+ }
+ object.add("blobs", blobsArray);
+
+ Debug.log(TestCase.ANALYTICS, "Sending analytics data for " + id);
+ Debug.log(TestCase.ANALYTICS, object.toString());
+
+ // Send async, we do not care about the result. If it fails, that's fine.
+ client.sendAsync(HttpRequest.newBuilder()
+ .uri(URI.create(API_URL))
+ .header("User-Agent", "Mozilla/5.0 Slimefun4 AnalyticsService")
+ .POST(HttpRequest.BodyPublishers.ofString(object.toString()))
+ .build(),
+ HttpResponse.BodyHandlers.discarding()
+ ).thenAcceptAsync((res) -> {
+ if (res.statusCode() == 200) {
+ Debug.log(TestCase.ANALYTICS, "Analytics data for " + id + " sent successfully");
+ } else {
+ Debug.log(TestCase.ANALYTICS, "Analytics data for " + id + " failed to send - " + res.statusCode());
+ }
+ });
+ }
+}
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/AutoSavingService.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/AutoSavingService.java
index a0455323f6..060ce0d772 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/AutoSavingService.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/AutoSavingService.java
@@ -13,6 +13,8 @@
import org.bukkit.entity.Player;
import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile;
+import io.github.thebusybiscuit.slimefun4.core.debug.Debug;
+import io.github.thebusybiscuit.slimefun4.core.debug.TestCase;
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
import me.mrCookieSlime.Slimefun.api.BlockStorage;
@@ -39,9 +41,8 @@ public class AutoSavingService {
public void start(@Nonnull Slimefun plugin, int interval) {
this.interval = interval;
- plugin.getServer().getScheduler().runTaskTimer(plugin, this::saveAllPlayers, 2000L, interval * 60L * 20L);
+ plugin.getServer().getScheduler().runTaskTimerAsynchronously(plugin, this::saveAllPlayers, 2000L, interval * 60L * 20L);
plugin.getServer().getScheduler().runTaskTimerAsynchronously(plugin, this::saveAllBlocks, 2000L, interval * 60L * 20L);
-
}
/**
@@ -52,16 +53,30 @@ private void saveAllPlayers() {
Iterator iterator = PlayerProfile.iterator();
int players = 0;
+ Debug.log(TestCase.PLAYER_PROFILE_DATA, "Saving all players data");
+
while (iterator.hasNext()) {
PlayerProfile profile = iterator.next();
if (profile.isDirty()) {
players++;
profile.save();
+
+ Debug.log(TestCase.PLAYER_PROFILE_DATA, "Saved data for {} ({})",
+ profile.getPlayer() != null ? profile.getPlayer().getName() : "Unknown", profile.getUUID()
+ );
}
- if (profile.isMarkedForDeletion()) {
+ // Remove the PlayerProfile from memory if the player has left the server (marked from removal)
+ // and they're still not on the server
+ // At this point, we've already saved their profile so we can safely remove it
+ // without worry for having a data sync issue (e.g. data is changed but then we try to re-load older data)
+ if (profile.isMarkedForDeletion() && profile.getPlayer() == null) {
iterator.remove();
+
+ Debug.log(TestCase.PLAYER_PROFILE_DATA, "Removed data from memory for {}",
+ profile.getUUID()
+ );
}
}
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/MetricsService.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/MetricsService.java
index e186004c4e..d5fc57c879 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/MetricsService.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/MetricsService.java
@@ -4,11 +4,23 @@
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
+import java.net.URI;
import java.net.URL;
import java.net.URLClassLoader;
+import java.net.http.HttpClient;
+import java.net.http.HttpClient.Redirect;
+import java.net.http.HttpRequest;
+import java.net.http.HttpResponse;
+import java.net.http.HttpResponse.BodyHandler;
+import java.net.http.HttpResponse.BodySubscriber;
+import java.nio.ByteBuffer;
import java.nio.file.Files;
+import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
-import java.util.concurrent.atomic.AtomicInteger;
+import java.time.Duration;
+import java.util.List;
+import java.util.concurrent.CompletionStage;
+import java.util.concurrent.Flow.Subscription;
import java.util.logging.Level;
import javax.annotation.Nonnull;
@@ -16,14 +28,12 @@
import org.bukkit.plugin.Plugin;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonParseException;
+
import io.github.bakedlibs.dough.common.CommonPatterns;
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
-
-import kong.unirest.GetRequest;
-import kong.unirest.HttpResponse;
-import kong.unirest.JsonNode;
-import kong.unirest.Unirest;
-import kong.unirest.UnirestException;
+import io.github.thebusybiscuit.slimefun4.utils.JsonUtils;
/**
* This Class represents a Metrics Service that sends data to https://bstats.org/
@@ -66,22 +76,12 @@ public class MetricsService {
private final Slimefun plugin;
private final File parentFolder;
private final File metricsModuleFile;
+ private final HttpClient client = HttpClient.newBuilder().followRedirects(Redirect.NORMAL).build();
private URLClassLoader moduleClassLoader;
private String metricVersion = null;
private boolean hasDownloadedUpdate = false;
- static {
- // @formatter:off (We want this to stay this nicely aligned :D )
- Unirest.config()
- .concurrency(2, 1)
- .setDefaultHeader("User-Agent", "MetricsModule Auto-Updater")
- .setDefaultHeader("Accept", "application/vnd.github.v3+json")
- .enableCookieManagement(false)
- .cookieSpec("ignoreCookies");
- // @formatter:on
- }
-
/**
* This constructs a new instance of our {@link MetricsService}.
*
@@ -199,20 +199,16 @@ public boolean checkForUpdate(@Nullable String currentVersion) {
*/
private int getLatestVersion() {
try {
- HttpResponse response = Unirest.get(RELEASES_URL).asJson();
+ HttpResponse response = client.send(buildBaseRequest(URI.create(RELEASES_URL)), HttpResponse.BodyHandlers.ofString());
- if (!response.isSuccess()) {
+ if (response.statusCode() < 200 || response.statusCode() >= 300) {
return -1;
}
- JsonNode node = response.getBody();
+ JsonElement element = JsonUtils.parseString(response.body());
- if (node == null) {
- return -1;
- }
-
- return node.getObject().getInt("tag_name");
- } catch (UnirestException e) {
+ return element.getAsJsonObject().get("tag_name").getAsInt();
+ } catch (IOException | InterruptedException | JsonParseException e) {
plugin.getLogger().log(Level.WARNING, "Failed to fetch latest builds for Metrics: {0}", e.getMessage());
return -1;
}
@@ -235,19 +231,12 @@ private boolean download(int version) {
Files.delete(file.toPath());
}
- AtomicInteger lastPercentPosted = new AtomicInteger();
- GetRequest request = Unirest.get(DOWNLOAD_URL + "/" + version + "/" + JAR_NAME + ".jar");
-
- HttpResponse response = request.downloadMonitor((b, fileName, bytesWritten, totalBytes) -> {
- int percent = (int) (20 * (Math.round((((double) bytesWritten / totalBytes) * 100) / 20)));
+ HttpResponse response = client.send(
+ buildBaseRequest(URI.create(DOWNLOAD_URL + "/" + version + "/" + JAR_NAME + ".jar")),
+ downloadMonitor(HttpResponse.BodyHandlers.ofFile(file.toPath()))
+ );
- if (percent != 0 && percent != lastPercentPosted.get()) {
- plugin.getLogger().info("# Downloading... " + percent + "% " + "(" + bytesWritten + "/" + totalBytes + " bytes)");
- lastPercentPosted.set(percent);
- }
- }).asFile(file.getPath());
-
- if (response.isSuccess()) {
+ if (response.statusCode() >= 200 && response.statusCode() < 300) {
plugin.getLogger().log(Level.INFO, "Successfully downloaded {0} build: #{1}", new Object[] { JAR_NAME, version });
// Replace the metric file with the new one
@@ -257,8 +246,10 @@ private boolean download(int version) {
metricVersion = String.valueOf(version);
hasDownloadedUpdate = true;
return true;
+ } else {
+ plugin.getLogger().log(Level.WARNING, "Failed to download the latest jar file from GitHub. Response code: {0}", response.statusCode());
}
- } catch (UnirestException e) {
+ } catch (InterruptedException | JsonParseException e) {
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) {
plugin.getLogger().log(Level.WARNING, "Failed to replace the old metric file with the new one. Please do this manually! Error: {0}", e.getMessage());
@@ -287,4 +278,58 @@ public String getVersion() {
public boolean hasAutoUpdates() {
return Slimefun.instance().getConfig().getBoolean("metrics.auto-update");
}
+
+ private HttpRequest buildBaseRequest(@Nonnull URI uri) {
+ return HttpRequest.newBuilder()
+ .uri(uri)
+ .timeout(Duration.ofSeconds(5))
+ .header("User-Agent", "MetricsModule Auto-Updater")
+ .header("Accept", "application/vnd.github.v3+json")
+ .build();
+ }
+
+ private BodyHandler downloadMonitor(BodyHandler h) {
+ return info -> new BodySubscriber() {
+
+ private BodySubscriber delegateSubscriber = h.apply(info);
+ private int lastPercentPosted = 0;
+ private long bytesWritten = 0;
+
+ @Override
+ public void onSubscribe(Subscription subscription) {
+ delegateSubscriber.onSubscribe(subscription);
+ }
+
+ @Override
+ public void onNext(List item) {
+ bytesWritten += item.stream().mapToLong(ByteBuffer::capacity).sum();
+ long totalBytes = info.headers().firstValue("Content-Length").map(Long::parseLong).orElse(-1L);
+
+ int percent = (int) (20 * (Math.round((((double) bytesWritten / totalBytes) * 100) / 20)));
+
+ if (percent != 0 && percent != lastPercentPosted) {
+ plugin.getLogger().info("# Downloading... " + percent + "% " + "(" + bytesWritten + "/" + totalBytes + " bytes)");
+ lastPercentPosted = percent;
+ }
+
+ delegateSubscriber.onNext(item);
+ }
+
+ @Override
+ public void onError(Throwable throwable) {
+ delegateSubscriber.onError(throwable);
+
+ }
+
+ @Override
+ public void onComplete() {
+ delegateSubscriber.onComplete();
+ }
+
+ @Override
+ public CompletionStage getBody() {
+ return delegateSubscriber.getBody();
+ }
+ };
+ }
}
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/ThreadService.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/ThreadService.java
new file mode 100644
index 0000000000..a5aa0c58e0
--- /dev/null
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/ThreadService.java
@@ -0,0 +1,99 @@
+package io.github.thebusybiscuit.slimefun4.core.services;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.TimeUnit;
+
+import javax.annotation.ParametersAreNonnullByDefault;
+
+import org.bukkit.plugin.java.JavaPlugin;
+import org.bukkit.scheduler.BukkitScheduler;
+
+public final class ThreadService {
+
+ private final ThreadGroup group;
+ private final ExecutorService cachedPool;
+ private final ScheduledExecutorService scheduledPool;
+
+ public ThreadService(JavaPlugin plugin) {
+ this.group = new ThreadGroup(plugin.getName());
+ this.cachedPool = Executors.newCachedThreadPool(new ThreadFactory() {
+ @Override
+ public Thread newThread(Runnable r) {
+ return new Thread(group, r, plugin.getName() + " - ThreadService");
+ }
+ });
+
+ this.scheduledPool = Executors.newScheduledThreadPool(1, new ThreadFactory() {
+ @Override
+ public Thread newThread(Runnable r) {
+ return new Thread(group, r, plugin.getName() + " - ScheduledThreadService");
+ }
+ });
+ }
+
+ /**
+ * Invoke a new thread from the cached thread pool with the given name.
+ * This is a much better alternative to using
+ * {@link BukkitScheduler#runTaskAsynchronously(org.bukkit.plugin.Plugin, Runnable)}
+ * as this will show not only the plugin but a useful name.
+ * By default, Bukkit will use "Craft Scheduler Thread - {@literal } - {@literal }" which is nice to show the plugin but
+ * it's impossible to track exactly what thread that is.
+ *
+ * @param plugin The {@link JavaPlugin} that is creating this thread
+ * @param name The name of this thread, this will be prefixed with the plugin's name
+ * @param runnable The {@link Runnable} to execute
+ */
+ @ParametersAreNonnullByDefault
+ public void newThread(JavaPlugin plugin, String name, Runnable runnable) {
+ cachedPool.submit(() -> {
+ // This is a bit of a hack, but it's the only way to have the thread name be as desired
+ Thread.currentThread().setName(plugin.getName() + " - " + name);
+ runnable.run();
+ });
+ }
+
+ /**
+ * Invoke a new scheduled thread from the cached thread pool with the given name.
+ * This is a much better alternative to using
+ * {@link BukkitScheduler#runTaskTimerAsynchronously(org.bukkit.plugin.Plugin, Runnable, long, long)}
+ * as this will show not only the plugin but a useful name.
+ * By default, Bukkit will use "Craft Scheduler Thread - {@literal } - {@literal }" which is nice to show the plugin but
+ * it's impossible to track exactly what thread that is.
+ *
+ * @param plugin The {@link JavaPlugin} that is creating this thread
+ * @param name The name of this thread, this will be prefixed with the plugin's name
+ * @param runnable The {@link Runnable} to execute
+ */
+ @ParametersAreNonnullByDefault
+ public void newScheduledThread(
+ JavaPlugin plugin,
+ String name,
+ Runnable runnable,
+ long delay,
+ long period,
+ TimeUnit unit
+ ) {
+ this.scheduledPool.scheduleWithFixedDelay(() -> {
+ // This is a bit of a hack, but it's the only way to have the thread name be as desired
+ Thread.currentThread().setName(plugin.getName() + " - " + name);
+ runnable.run();
+ }, delay, delay, unit);
+ }
+
+ /**
+ * Get the caller of a given method, this should only be used for debugging purposes and is not performant.
+ *
+ * @return The caller of the method that called this method.
+ */
+ public static String getCaller() {
+ // First item will be getting the call stack
+ // Second item will be this call
+ // Third item will be the func we care about being called
+ // And finally will be the caller
+ StackTraceElement element = Thread.currentThread().getStackTrace()[3];
+ return element.getClassName() + "." + element.getMethodName() + ":" + element.getLineNumber();
+ }
+}
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/UpdaterService.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/UpdaterService.java
index b556789a91..ac21007fce 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/UpdaterService.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/UpdaterService.java
@@ -1,6 +1,7 @@
package io.github.thebusybiscuit.slimefun4.core.services;
import java.io.File;
+import java.util.concurrent.ExecutionException;
import java.util.logging.Level;
import javax.annotation.Nonnull;
@@ -110,6 +111,29 @@ public int getBuildNumber() {
return -1;
}
+ public int getLatestVersion() {
+ if (updater != null && updater.getLatestVersion().isDone()) {
+ PrefixedVersion version;
+ try {
+ version = updater.getLatestVersion().get();
+ return version.getVersionNumber();
+ } catch (InterruptedException | ExecutionException e) {
+ return -1;
+ }
+ }
+
+ return -1;
+ }
+
+ public boolean isLatestVersion() {
+ if (getBuildNumber() == -1 || getLatestVersion() == -1) {
+ // We don't know if we're latest so just report we are
+ return true;
+ }
+
+ return getBuildNumber() == getLatestVersion();
+ }
+
/**
* This will start the {@link UpdaterService} and check for updates.
* If it can find an update it will automatically be installed.
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/ContributionsConnector.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/ContributionsConnector.java
index 7dd4970552..4eb9d92637 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/ContributionsConnector.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/ContributionsConnector.java
@@ -9,11 +9,11 @@
import javax.annotation.Nonnull;
import javax.annotation.ParametersAreNonnullByDefault;
-import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
-import kong.unirest.JsonNode;
-import kong.unirest.json.JSONArray;
-import kong.unirest.json.JSONObject;
+import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
class ContributionsConnector extends GitHubConnector {
@@ -90,11 +90,11 @@ public boolean hasFinished() {
}
@Override
- public void onSuccess(@Nonnull JsonNode response) {
+ public void onSuccess(@Nonnull JsonElement response) {
finished = true;
- if (response.isArray()) {
- computeContributors(response.getArray());
+ if (response.isJsonArray()) {
+ computeContributors(response.getAsJsonArray());
} else {
Slimefun.logger().log(Level.WARNING, "Received an unusual answer from GitHub, possibly a timeout? ({0})", response);
}
@@ -123,13 +123,13 @@ public Map getParameters() {
return parameters;
}
- private void computeContributors(@Nonnull JSONArray array) {
- for (int i = 0; i < array.length(); i++) {
- JSONObject object = array.getJSONObject(i);
+ private void computeContributors(@Nonnull JsonArray array) {
+ for (JsonElement element : array) {
+ JsonObject object = element.getAsJsonObject();
- String name = object.getString("login");
- int commits = object.getInt("contributions");
- String profile = object.getString("html_url");
+ String name = object.get("login").getAsString();
+ int commits = object.get("contributions").getAsInt();
+ String profile = object.get("html_url").getAsString();
if (!ignoredAccounts.contains(name)) {
String username = aliases.getOrDefault(name, name);
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/GitHubActivityConnector.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/GitHubActivityConnector.java
index b298195e7b..60697f1345 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/GitHubActivityConnector.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/GitHubActivityConnector.java
@@ -7,10 +7,10 @@
import javax.annotation.Nonnull;
import javax.annotation.ParametersAreNonnullByDefault;
-import io.github.thebusybiscuit.slimefun4.utils.NumberUtils;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
-import kong.unirest.JsonNode;
-import kong.unirest.json.JSONObject;
+import io.github.thebusybiscuit.slimefun4.utils.NumberUtils;
class GitHubActivityConnector extends GitHubConnector {
@@ -23,11 +23,11 @@ class GitHubActivityConnector extends GitHubConnector {
}
@Override
- public void onSuccess(@Nonnull JsonNode response) {
- JSONObject object = response.getObject();
- int forks = object.getInt("forks");
- int stars = object.getInt("stargazers_count");
- LocalDateTime lastPush = NumberUtils.parseGitHubDate(object.getString("pushed_at"));
+ public void onSuccess(@Nonnull JsonElement response) {
+ JsonObject object = response.getAsJsonObject();
+ int forks = object.get("forks").getAsInt();
+ int stars = object.get("stargazers_count").getAsInt();
+ LocalDateTime lastPush = NumberUtils.parseGitHubDate(object.get("pushed_at").getAsString());
callback.accept(forks, stars, lastPush);
}
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/GitHubConnector.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/GitHubConnector.java
index 422ed31787..6b7d89e1ea 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/GitHubConnector.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/GitHubConnector.java
@@ -6,7 +6,12 @@
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
+import java.net.URI;
+import java.net.URISyntaxException;
import java.net.URL;
+import java.net.http.HttpClient;
+import java.net.http.HttpRequest;
+import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.logging.Level;
@@ -14,13 +19,11 @@
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
-import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonParseException;
-import kong.unirest.HttpResponse;
-import kong.unirest.JsonNode;
-import kong.unirest.Unirest;
-import kong.unirest.UnirestException;
-import kong.unirest.json.JSONException;
+import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
+import io.github.thebusybiscuit.slimefun4.utils.JsonUtils;
/**
* The {@link GitHubConnector} is used to connect to the GitHub API service.
@@ -34,6 +37,7 @@ abstract class GitHubConnector {
private static final String API_URL = "https://api.github.com/";
private static final String USER_AGENT = "Slimefun4 (https://github.com/Slimefun)";
+ private static final HttpClient client = HttpClient.newHttpClient();
protected final GitHubService github;
private final String url;
@@ -83,7 +87,7 @@ abstract class GitHubConnector {
* @param response
* The response
*/
- public abstract void onSuccess(@Nonnull JsonNode response);
+ public abstract void onSuccess(@Nonnull JsonElement response);
/**
* This method is called when the connection has failed.
@@ -105,38 +109,44 @@ void download() {
}
try {
- // @formatter:off
- HttpResponse response = Unirest.get(url)
- .queryString(getParameters())
- .header("User-Agent", USER_AGENT)
- .asJson();
- // @formatter:on
-
- if (response.isSuccess()) {
- onSuccess(response.getBody());
- writeCacheFile(response.getBody());
+ String params = getParameters().entrySet().stream()
+ .map(p -> p.getKey() + "=" + p.getValue())
+ .reduce((p1, p2) -> p1 + "&" + p2)
+ .map(s -> "?" + s)
+ .orElse("");
+ URI uri = new URI(url + params);
+
+ HttpResponse response = client.send(
+ HttpRequest.newBuilder(uri).header("User-Agent", USER_AGENT).build(),
+ HttpResponse.BodyHandlers.ofString()
+ );
+ JsonElement element = JsonUtils.parseString(response.body());
+
+ if (response.statusCode() >= 200 && response.statusCode() < 300) {
+ onSuccess(element);
+ writeCacheFile(element);
} else {
if (github.isLoggingEnabled()) {
- Slimefun.logger().log(Level.WARNING, "Failed to fetch {0}: {1} - {2}", new Object[] { url, response.getStatus(), response.getBody() });
+ Slimefun.logger().log(Level.WARNING, "Failed to fetch {0}: {1} - {2}", new Object[] { url, response.statusCode(), element });
}
// It has the cached file, let's just read that then
if (file.exists()) {
- JsonNode cache = readCacheFile();
+ JsonElement cache = readCacheFile();
if (cache != null) {
onSuccess(cache);
}
}
}
- } catch (UnirestException e) {
+ } catch (IOException | InterruptedException | JsonParseException | URISyntaxException e) {
if (github.isLoggingEnabled()) {
Slimefun.logger().log(Level.WARNING, "Could not connect to GitHub in time.", e);
}
// It has the cached file, let's just read that then
if (file.exists()) {
- JsonNode cache = readCacheFile();
+ JsonElement cache = readCacheFile();
if (cache != null) {
onSuccess(cache);
@@ -150,16 +160,16 @@ void download() {
}
@Nullable
- private JsonNode readCacheFile() {
+ private JsonElement readCacheFile() {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8))) {
- return new JsonNode(reader.readLine());
- } catch (IOException | JSONException e) {
+ return JsonUtils.parseString(reader.readLine());
+ } catch (IOException | JsonParseException e) {
Slimefun.logger().log(Level.WARNING, "Failed to read Github cache file: {0} - {1}: {2}", new Object[] { file.getName(), e.getClass().getSimpleName(), e.getMessage() });
return null;
}
}
- private void writeCacheFile(@Nonnull JsonNode node) {
+ private void writeCacheFile(@Nonnull JsonElement node) {
try (FileOutputStream output = new FileOutputStream(file)) {
output.write(node.toString().getBytes(StandardCharsets.UTF_8));
} catch (IOException e) {
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/GitHubIssuesConnector.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/GitHubIssuesConnector.java
index 81cd1ac5d3..96a4237e1e 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/GitHubIssuesConnector.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/GitHubIssuesConnector.java
@@ -7,11 +7,11 @@
import javax.annotation.Nonnull;
import javax.annotation.ParametersAreNonnullByDefault;
-import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
-import kong.unirest.JsonNode;
-import kong.unirest.json.JSONArray;
-import kong.unirest.json.JSONObject;
+import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
class GitHubIssuesConnector extends GitHubConnector {
@@ -24,15 +24,15 @@ class GitHubIssuesConnector extends GitHubConnector {
}
@Override
- public void onSuccess(@Nonnull JsonNode response) {
- if (response.isArray()) {
- JSONArray array = response.getArray();
+ public void onSuccess(@Nonnull JsonElement response) {
+ if (response.isJsonArray()) {
+ JsonArray array = response.getAsJsonArray();
int issues = 0;
int pullRequests = 0;
- for (int i = 0; i < array.length(); i++) {
- JSONObject obj = array.getJSONObject(i);
+ for (JsonElement element : array) {
+ JsonObject obj = element.getAsJsonObject();
if (obj.has("pull_request")) {
pullRequests++;
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/profiler/SlimefunProfiler.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/profiler/SlimefunProfiler.java
index 2a1292225a..408fdc439e 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/profiler/SlimefunProfiler.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/profiler/SlimefunProfiler.java
@@ -22,6 +22,8 @@
import org.bukkit.block.Block;
import org.bukkit.scheduler.BukkitScheduler;
+import com.google.common.util.concurrent.AtomicDouble;
+
import io.github.thebusybiscuit.slimefun4.api.SlimefunAddon;
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem;
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
@@ -87,6 +89,8 @@ public class SlimefunProfiler {
private final AtomicLong totalMsTicked = new AtomicLong();
private final AtomicInteger ticksPassed = new AtomicInteger();
+ private final AtomicLong totalNsTicked = new AtomicLong();
+ private final AtomicDouble averageTimingsPerMachine = new AtomicDouble();
/**
* This method terminates the {@link SlimefunProfiler}.
@@ -222,11 +226,14 @@ private void finishReport() {
totalElapsedTime = timings.values().stream().mapToLong(Long::longValue).sum();
+ averageTimingsPerMachine.getAndSet(timings.values().stream().mapToLong(Long::longValue).average().orElse(0));
+
/*
* We log how many milliseconds have been ticked, and how many ticks have passed
* This is so when bStats requests the average timings, they're super quick to figure out
*/
totalMsTicked.addAndGet(TimeUnit.NANOSECONDS.toMillis(totalElapsedTime));
+ totalNsTicked.addAndGet(totalElapsedTime);
ticksPassed.incrementAndGet();
if (!requests.isEmpty()) {
@@ -416,4 +423,26 @@ public long getAndResetAverageTimings() {
return l;
}
+
+ /**
+ * Get and reset the average nanosecond timing for this {@link SlimefunProfiler}.
+ *
+ * @return The average nanosecond timing for this {@link SlimefunProfiler}.
+ */
+ public double getAndResetAverageNanosecondTimings() {
+ long l = totalNsTicked.get() / ticksPassed.get();
+ totalNsTicked.set(0);
+ ticksPassed.set(0);
+
+ return l;
+ }
+
+ /**
+ * Get and reset the average millisecond timing for each machine.
+ *
+ * @return The average millisecond timing for each machine.
+ */
+ public double getAverageTimingsPerMachine() {
+ return averageTimingsPerMachine.getAndSet(0);
+ }
}
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/Slimefun.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/Slimefun.java
index 28233ea741..1be851ba17 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/Slimefun.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/Slimefun.java
@@ -42,6 +42,7 @@
import io.github.thebusybiscuit.slimefun4.core.SlimefunRegistry;
import io.github.thebusybiscuit.slimefun4.core.commands.SlimefunCommand;
import io.github.thebusybiscuit.slimefun4.core.networks.NetworkManager;
+import io.github.thebusybiscuit.slimefun4.core.services.AnalyticsService;
import io.github.thebusybiscuit.slimefun4.core.services.AutoSavingService;
import io.github.thebusybiscuit.slimefun4.core.services.BackupService;
import io.github.thebusybiscuit.slimefun4.core.services.BlockDataService;
@@ -52,6 +53,7 @@
import io.github.thebusybiscuit.slimefun4.core.services.MinecraftRecipeService;
import io.github.thebusybiscuit.slimefun4.core.services.PerWorldSettingsService;
import io.github.thebusybiscuit.slimefun4.core.services.PermissionsService;
+import io.github.thebusybiscuit.slimefun4.core.services.ThreadService;
import io.github.thebusybiscuit.slimefun4.core.services.UpdaterService;
import io.github.thebusybiscuit.slimefun4.core.services.github.GitHubService;
import io.github.thebusybiscuit.slimefun4.core.services.holograms.HologramsService;
@@ -182,6 +184,8 @@ public class Slimefun extends JavaPlugin implements SlimefunAddon {
private final MinecraftRecipeService recipeService = new MinecraftRecipeService(this);
private final HologramsService hologramsService = new HologramsService(this);
private final SoundService soundService = new SoundService(this);
+ private final ThreadService threadService = new ThreadService(this);
+ private final AnalyticsService analyticsService = new AnalyticsService(this);
// Some other things we need
private final IntegrationsManager integrations = new IntegrationsManager(this);
@@ -309,8 +313,9 @@ private void onPluginStart() {
playerStorage = new LegacyStorage();
logger.log(Level.INFO, "Using legacy storage for player data");
- // Setting up bStats
+ // Setting up bStats and analytics
new Thread(metricsService::start, "Slimefun Metrics").start();
+ analyticsService.start();
// Starting the Auto-Updater
if (config.getBoolean("options.auto-update")) {
@@ -520,11 +525,12 @@ private boolean isVersionUnsupported() {
// Now check the actual Version of Minecraft
int version = PaperLib.getMinecraftVersion();
+ int patchVersion = PaperLib.getMinecraftPatchVersion();
if (version > 0) {
// Check all supported versions of Minecraft
for (MinecraftVersion supportedVersion : MinecraftVersion.values()) {
- if (supportedVersion.isMinecraftVersion(version)) {
+ if (supportedVersion.isMinecraftVersion(version, patchVersion)) {
minecraftVersion = supportedVersion;
return false;
}
@@ -901,6 +907,17 @@ public static SoundService getSoundService() {
return instance.metricsService;
}
+ /**
+ * This method returns the {@link AnalyticsService} of Slimefun.
+ * It is used to handle sending analytic information.
+ *
+ * @return The {@link AnalyticsService} for Slimefun
+ */
+ public static @Nonnull AnalyticsService getAnalyticsService() {
+ validateInstance();
+ return instance.analyticsService;
+ }
+
/**
* This method returns the {@link GitHubService} of Slimefun.
* It is used to retrieve data from GitHub repositories.
@@ -1068,4 +1085,14 @@ public static boolean isNewlyInstalled() {
public static @Nonnull Storage getPlayerStorage() {
return instance().playerStorage;
}
+
+ /**
+ * This method returns the {@link ThreadService} of Slimefun.
+ * Do not use this if you're an addon. Please make your own {@link ThreadService}.
+ *
+ * @return The {@link ThreadService} for Slimefun
+ */
+ public static @Nonnull ThreadService getThreadService() {
+ return instance().threadService;
+ }
}
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/SlimefunItems.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/SlimefunItems.java
index 8695759316..d3adb16e0b 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/SlimefunItems.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/SlimefunItems.java
@@ -22,6 +22,7 @@
import io.github.thebusybiscuit.slimefun4.utils.ChatUtils;
import io.github.thebusybiscuit.slimefun4.utils.HeadTexture;
import io.github.thebusybiscuit.slimefun4.utils.LoreBuilder;
+import io.github.thebusybiscuit.slimefun4.utils.compatibility.VersionedEnchantment;
import io.github.thebusybiscuit.slimefun4.utils.itemstack.ColoredFireworkStar;
/**
@@ -192,8 +193,8 @@ private SlimefunItems() {}
GRANDPAS_WALKING_STICK.addUnsafeEnchantment(Enchantment.KNOCKBACK, 5);
BLADE_OF_VAMPIRES.addUnsafeEnchantment(Enchantment.FIRE_ASPECT, 2);
- BLADE_OF_VAMPIRES.addUnsafeEnchantment(Enchantment.DURABILITY, 4);
- BLADE_OF_VAMPIRES.addUnsafeEnchantment(Enchantment.DAMAGE_ALL, 2);
+ BLADE_OF_VAMPIRES.addUnsafeEnchantment(VersionedEnchantment.UNBREAKING, 4);
+ BLADE_OF_VAMPIRES.addUnsafeEnchantment(VersionedEnchantment.SHARPNESS, 2);
}
/* Bows */
@@ -212,8 +213,8 @@ private SlimefunItems() {}
public static final SlimefunItemStack CLIMBING_PICK = new SlimefunItemStack("CLIMBING_PICK", Material.IRON_PICKAXE, "&bClimbing Pick", "", "&fAllows you to climb certain surfaces", "&fby right-clicking.", "&fEnchant this pick with Efficiency to", "&fclimb even faster!");
static {
- COBALT_PICKAXE.addUnsafeEnchantment(Enchantment.DURABILITY, 10);
- COBALT_PICKAXE.addUnsafeEnchantment(Enchantment.DIG_SPEED, 6);
+ COBALT_PICKAXE.addUnsafeEnchantment(VersionedEnchantment.UNBREAKING, 10);
+ COBALT_PICKAXE.addUnsafeEnchantment(VersionedEnchantment.EFFICIENCY, 6);
}
/* Armor */
@@ -304,7 +305,7 @@ private SlimefunItems() {}
static {
Map cactusEnchs = new HashMap<>();
cactusEnchs.put(Enchantment.THORNS, 3);
- cactusEnchs.put(Enchantment.DURABILITY, 6);
+ cactusEnchs.put(VersionedEnchantment.UNBREAKING, 6);
CACTUS_HELMET.addUnsafeEnchantments(cactusEnchs);
CACTUS_CHESTPLATE.addUnsafeEnchantments(cactusEnchs);
@@ -312,8 +313,8 @@ private SlimefunItems() {}
CACTUS_BOOTS.addUnsafeEnchantments(cactusEnchs);
Map damascusEnchs = new HashMap<>();
- damascusEnchs.put(Enchantment.DURABILITY, 5);
- damascusEnchs.put(Enchantment.PROTECTION_ENVIRONMENTAL, 5);
+ damascusEnchs.put(VersionedEnchantment.UNBREAKING, 5);
+ damascusEnchs.put(VersionedEnchantment.PROTECTION, 5);
DAMASCUS_STEEL_HELMET.addUnsafeEnchantments(damascusEnchs);
DAMASCUS_STEEL_CHESTPLATE.addUnsafeEnchantments(damascusEnchs);
@@ -321,8 +322,8 @@ private SlimefunItems() {}
DAMASCUS_STEEL_BOOTS.addUnsafeEnchantments(damascusEnchs);
Map reinforcedEnchs = new HashMap<>();
- reinforcedEnchs.put(Enchantment.DURABILITY, 9);
- reinforcedEnchs.put(Enchantment.PROTECTION_ENVIRONMENTAL, 9);
+ reinforcedEnchs.put(VersionedEnchantment.UNBREAKING, 9);
+ reinforcedEnchs.put(VersionedEnchantment.PROTECTION, 9);
REINFORCED_ALLOY_HELMET.addUnsafeEnchantments(reinforcedEnchs);
REINFORCED_ALLOY_CHESTPLATE.addUnsafeEnchantments(reinforcedEnchs);
@@ -330,22 +331,22 @@ private SlimefunItems() {}
REINFORCED_ALLOY_BOOTS.addUnsafeEnchantments(reinforcedEnchs);
Map gildedEnchs = new HashMap<>();
- gildedEnchs.put(Enchantment.DURABILITY, 6);
- gildedEnchs.put(Enchantment.PROTECTION_ENVIRONMENTAL, 8);
+ gildedEnchs.put(VersionedEnchantment.UNBREAKING, 6);
+ gildedEnchs.put(VersionedEnchantment.PROTECTION, 8);
GILDED_IRON_HELMET.addUnsafeEnchantments(gildedEnchs);
GILDED_IRON_CHESTPLATE.addUnsafeEnchantments(gildedEnchs);
GILDED_IRON_LEGGINGS.addUnsafeEnchantments(gildedEnchs);
GILDED_IRON_BOOTS.addUnsafeEnchantments(gildedEnchs);
- GOLDEN_HELMET_12K.addUnsafeEnchantment(Enchantment.DURABILITY, 10);
- GOLDEN_CHESTPLATE_12K.addUnsafeEnchantment(Enchantment.DURABILITY, 10);
- GOLDEN_LEGGINGS_12K.addUnsafeEnchantment(Enchantment.DURABILITY, 10);
- GOLDEN_BOOTS_12K.addUnsafeEnchantment(Enchantment.DURABILITY, 10);
+ GOLDEN_HELMET_12K.addUnsafeEnchantment(VersionedEnchantment.UNBREAKING, 10);
+ GOLDEN_CHESTPLATE_12K.addUnsafeEnchantment(VersionedEnchantment.UNBREAKING, 10);
+ GOLDEN_LEGGINGS_12K.addUnsafeEnchantment(VersionedEnchantment.UNBREAKING, 10);
+ GOLDEN_BOOTS_12K.addUnsafeEnchantment(VersionedEnchantment.UNBREAKING, 10);
Map slimeEnchs = new HashMap<>();
- slimeEnchs.put(Enchantment.DURABILITY, 4);
- slimeEnchs.put(Enchantment.PROTECTION_ENVIRONMENTAL, 2);
+ slimeEnchs.put(VersionedEnchantment.UNBREAKING, 4);
+ slimeEnchs.put(VersionedEnchantment.PROTECTION, 2);
SLIME_HELMET_STEEL.addUnsafeEnchantments(slimeEnchs);
SLIME_CHESTPLATE_STEEL.addUnsafeEnchantments(slimeEnchs);
@@ -353,8 +354,8 @@ private SlimefunItems() {}
SLIME_BOOTS_STEEL.addUnsafeEnchantments(slimeEnchs);
Map beeEnchs = new HashMap<>();
- beeEnchs.put(Enchantment.DURABILITY, 4);
- beeEnchs.put(Enchantment.PROTECTION_ENVIRONMENTAL, 2);
+ beeEnchs.put(VersionedEnchantment.UNBREAKING, 4);
+ beeEnchs.put(VersionedEnchantment.PROTECTION, 2);
BEE_HELMET.addUnsafeEnchantments(beeEnchs);
BEE_WINGS.addUnsafeEnchantments(beeEnchs);
@@ -567,10 +568,10 @@ private SlimefunItems() {}
public static final SlimefunItemStack STAFF_STORM = new SlimefunItemStack("STAFF_ELEMENTAL_STORM", Material.STICK, "&6Elemental Staff &7- &8&oStorm", "", "&7Element: &8&oStorm", "", "&eRight Click&7 to summon a lightning", LoreBuilder.usesLeft(StormStaff.MAX_USES));
static {
- STAFF_WIND.addUnsafeEnchantment(Enchantment.LUCK, 1);
+ STAFF_WIND.addUnsafeEnchantment(VersionedEnchantment.LUCK_OF_THE_SEA, 1);
STAFF_FIRE.addUnsafeEnchantment(Enchantment.FIRE_ASPECT, 5);
- STAFF_WATER.addUnsafeEnchantment(Enchantment.WATER_WORKER, 1);
- STAFF_STORM.addUnsafeEnchantment(Enchantment.DURABILITY, 1);
+ STAFF_WATER.addUnsafeEnchantment(VersionedEnchantment.AQUA_AFFINITY, 1);
+ STAFF_STORM.addUnsafeEnchantment(VersionedEnchantment.UNBREAKING, 1);
}
/* Multiblocks */
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/SurvivalSlimefunGuide.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/SurvivalSlimefunGuide.java
index 154150d979..83e43be65f 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/SurvivalSlimefunGuide.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/SurvivalSlimefunGuide.java
@@ -48,6 +48,7 @@
import io.github.thebusybiscuit.slimefun4.implementation.tasks.AsyncRecipeChoiceTask;
import io.github.thebusybiscuit.slimefun4.utils.ChatUtils;
import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils;
+import io.github.thebusybiscuit.slimefun4.utils.compatibility.VersionedItemFlag;
import io.github.thebusybiscuit.slimefun4.utils.itemstack.SlimefunGuideItem;
import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu;
@@ -360,7 +361,7 @@ public void openSearch(PlayerProfile profile, String input, boolean addToHistory
ItemStack itemstack = new CustomItemStack(slimefunItem.getItem(), meta -> {
ItemGroup itemGroup = slimefunItem.getItemGroup();
meta.setLore(Arrays.asList("", ChatColor.DARK_GRAY + "\u21E8 " + ChatColor.WHITE + itemGroup.getDisplayName(p)));
- meta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_ENCHANTS, ItemFlag.HIDE_POTION_EFFECTS);
+ meta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_ENCHANTS, VersionedItemFlag.HIDE_ADDITIONAL_TOOLTIP);
});
menu.addItem(index, itemstack);
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/MinerAndroid.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/MinerAndroid.java
index be397c5055..8d041bafb5 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/MinerAndroid.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/MinerAndroid.java
@@ -10,7 +10,6 @@
import org.bukkit.Effect;
import org.bukkit.Material;
import org.bukkit.OfflinePlayer;
-import org.bukkit.Particle;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.inventory.ItemStack;
@@ -24,6 +23,7 @@
import io.github.thebusybiscuit.slimefun4.core.services.sounds.SoundEffect;
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
import io.github.thebusybiscuit.slimefun4.utils.InfiniteBlockGenerator;
+import io.github.thebusybiscuit.slimefun4.utils.compatibility.VersionedParticle;
import io.github.thebusybiscuit.slimefun4.utils.tags.SlimefunTag;
import me.mrCookieSlime.Slimefun.api.BlockStorage;
@@ -149,7 +149,7 @@ private void breakBlock(BlockMenu menu, Collection drops, Block block
// "poof" a "new" block was generated
SoundEffect.MINER_ANDROID_BLOCK_GENERATION_SOUND.playAt(block);
- block.getWorld().spawnParticle(Particle.SMOKE_NORMAL, block.getX() + 0.5, block.getY() + 1.25, block.getZ() + 0.5, 8, 0.5, 0.5, 0.5, 0.015);
+ block.getWorld().spawnParticle(VersionedParticle.SMOKE, block.getX() + 0.5, block.getY() + 1.25, block.getZ() + 0.5, 8, 0.5, 0.5, 0.5, 0.015);
} else {
block.setType(Material.AIR);
}
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/ProgrammableAndroid.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/ProgrammableAndroid.java
index 471551575b..8db9826bc7 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/ProgrammableAndroid.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/ProgrammableAndroid.java
@@ -25,7 +25,6 @@
import org.bukkit.entity.Player;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockPlaceEvent;
-import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
@@ -55,8 +54,6 @@
import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config;
import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu;
-import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu.AdvancedMenuClickHandler;
-import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ClickAction;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.MachineFuel;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.interfaces.InventoryBlock;
import me.mrCookieSlime.Slimefun.Objects.handlers.BlockTicker;
@@ -847,18 +844,7 @@ private void constructMenu(@Nonnull BlockMenuPreset preset) {
preset.drawBackground(ChestMenuUtils.getOutputSlotTexture(), OUTPUT_BORDER);
for (int i : getOutputSlots()) {
- preset.addMenuClickHandler(i, new AdvancedMenuClickHandler() {
-
- @Override
- public boolean onClick(Player p, int slot, ItemStack cursor, ClickAction action) {
- return false;
- }
-
- @Override
- public boolean onClick(InventoryClickEvent e, Player p, int slot, ItemStack cursor, ClickAction action) {
- return cursor == null || cursor.getType() == null || cursor.getType() == Material.AIR;
- }
- });
+ preset.addMenuClickHandler(i, ChestMenuUtils.getDefaultOutputHandler());
}
preset.addItem(34, getFuelSource().getItem(), ChestMenuUtils.getEmptyClickHandler());
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/autocrafters/AbstractAutoCrafter.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/autocrafters/AbstractAutoCrafter.java
index 380c7a1273..b75d3c6643 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/autocrafters/AbstractAutoCrafter.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/autocrafters/AbstractAutoCrafter.java
@@ -14,7 +14,6 @@
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
-import org.bukkit.Particle;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.BlockState;
@@ -41,6 +40,7 @@
import io.github.thebusybiscuit.slimefun4.implementation.tasks.AsyncRecipeChoiceTask;
import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils;
import io.github.thebusybiscuit.slimefun4.utils.HeadTexture;
+import io.github.thebusybiscuit.slimefun4.utils.compatibility.VersionedParticle;
import io.github.thebusybiscuit.slimefun4.utils.tags.SlimefunTag;
import io.papermc.lib.PaperLib;
import io.papermc.lib.features.blockstatesnapshot.BlockStateSnapshotResult;
@@ -180,7 +180,7 @@ protected void tick(@Nonnull Block b, @Nonnull Config data) {
if (craft(inv, recipe)) {
// We are done crafting!
Location loc = b.getLocation().add(0.5, 0.8, 0.5);
- b.getWorld().spawnParticle(Particle.VILLAGER_HAPPY, loc, 6);
+ b.getWorld().spawnParticle(VersionedParticle.HAPPY_VILLAGER, loc, 6);
removeCharge(b.getLocation(), getEnergyConsumption());
}
}
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/blocks/Crucible.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/blocks/Crucible.java
index 2e0d31b489..f11e7a35ad 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/blocks/Crucible.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/blocks/Crucible.java
@@ -8,7 +8,6 @@
import javax.annotation.ParametersAreNonnullByDefault;
import org.bukkit.Material;
-import org.bukkit.Particle;
import org.bukkit.Tag;
import org.bukkit.World.Environment;
import org.bukkit.block.Block;
@@ -30,6 +29,7 @@
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
+import io.github.thebusybiscuit.slimefun4.utils.compatibility.VersionedParticle;
import io.github.thebusybiscuit.slimefun4.utils.tags.SlimefunTag;
import me.mrCookieSlime.Slimefun.api.BlockStorage;
@@ -165,7 +165,7 @@ private void generateLiquid(@Nonnull Block block, boolean isWater) {
// Fixes #2877 - If water in the nether is disabled, abort and play an effect.
if (isWater && block.getWorld().getEnvironment() == Environment.NETHER && !allowWaterInNether.getValue()) {
// We will still consume the items but won't generate water in the Nether.
- block.getWorld().spawnParticle(Particle.SMOKE_NORMAL, block.getLocation().add(0.5, 0.5, 0.5), 4);
+ block.getWorld().spawnParticle(VersionedParticle.SMOKE, block.getLocation().add(0.5, 0.5, 0.5), 4);
SoundEffect.CRUCIBLE_GENERATE_LIQUID_SOUND.playAt(block);
return;
}
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/gadgets/MultiTool.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/gadgets/MultiTool.java
index 56707206d4..d608742da4 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/gadgets/MultiTool.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/gadgets/MultiTool.java
@@ -1,17 +1,20 @@
package io.github.thebusybiscuit.slimefun4.implementation.items.electric.gadgets;
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
-import java.util.UUID;
+import java.util.regex.Pattern;
import javax.annotation.Nonnull;
import javax.annotation.ParametersAreNonnullByDefault;
+import io.github.bakedlibs.dough.common.ChatColors;
+import io.github.bakedlibs.dough.data.persistent.PersistentDataAPI;
import org.bukkit.ChatColor;
+import org.bukkit.NamespacedKey;
+import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.ItemMeta;
import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup;
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem;
@@ -22,22 +25,25 @@
import io.github.thebusybiscuit.slimefun4.core.handlers.ItemUseHandler;
import io.github.thebusybiscuit.slimefun4.core.handlers.ToolUseHandler;
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
+import io.github.thebusybiscuit.slimefun4.utils.compatibility.VersionedEntityType;
/**
* The {@link MultiTool} is an electric device which can mimic
* the behaviour of any other {@link SlimefunItem}.
- *
- * @author TheBusyBiscuit
*
+ * @author TheBusyBiscuit
*/
public class MultiTool extends SlimefunItem implements Rechargeable {
private static final float COST = 0.3F;
- private final Map selectedMode = new HashMap<>();
private final List modes = new ArrayList<>();
private final float capacity;
+ private static final NamespacedKey key = new NamespacedKey(Slimefun.instance(), "multitool_mode");
+ private static final String LORE_PREFIX = ChatColors.color("&8\u21E8 &7Mode: ");
+ private static final Pattern REGEX = Pattern.compile(ChatColors.color("(&c&o)?" + LORE_PREFIX) + "(.+)");
+
@ParametersAreNonnullByDefault
public MultiTool(ItemGroup itemGroup, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe, float capacity, String... items) {
super(itemGroup, item, recipeType, recipe);
@@ -73,17 +79,15 @@ protected ItemUseHandler getItemUseHandler() {
return e -> {
Player p = e.getPlayer();
ItemStack item = e.getItem();
+ ItemMeta meta = item.getItemMeta();
e.cancel();
- int index = selectedMode.getOrDefault(p.getUniqueId(), 0);
+ int index = PersistentDataAPI.getInt(meta, key, 0);
+ SlimefunItem sfItem = modes.get(index).getItem();
if (!p.isSneaking()) {
- if (removeItemCharge(item, COST)) {
- SlimefunItem sfItem = modes.get(index).getItem();
-
- if (sfItem != null) {
- sfItem.callItemHandler(ItemUseHandler.class, handler -> handler.onRightClick(e));
- }
+ if (sfItem != null && removeItemCharge(item, COST)) {
+ sfItem.callItemHandler(ItemUseHandler.class, handler -> handler.onRightClick(e));
}
} else {
index = nextIndex(index);
@@ -91,7 +95,28 @@ protected ItemUseHandler getItemUseHandler() {
SlimefunItem selectedItem = modes.get(index).getItem();
String itemName = selectedItem != null ? selectedItem.getItemName() : "Unknown";
Slimefun.getLocalization().sendMessage(p, "messages.multi-tool.mode-change", true, msg -> msg.replace("%device%", "Multi Tool").replace("%mode%", ChatColor.stripColor(itemName)));
- selectedMode.put(p.getUniqueId(), index);
+
+ PersistentDataAPI.setInt(meta, key, index);
+
+ List lore = meta.hasLore() ? meta.getLore() : new ArrayList<>();
+
+ boolean regexMatchFound = false;
+ for (int i = 0; i < lore.size(); i++) {
+ String line = lore.get(i);
+
+ if (REGEX.matcher(line).matches()) {
+ lore.set(i, LORE_PREFIX + ChatColor.stripColor(itemName));
+ regexMatchFound = true;
+ break;
+ }
+ }
+
+ if (!regexMatchFound) {
+ lore.add(2, LORE_PREFIX + ChatColor.stripColor(itemName));
+ }
+
+ meta.setLore(lore);
+ item.setItemMeta(meta);
}
};
}
@@ -109,15 +134,13 @@ private ToolUseHandler getToolUseHandler() {
private EntityInteractHandler getEntityInteractionHandler() {
return (e, item, offhand) -> {
// Fixes #2217 - Prevent them from being used to shear entities
- switch (e.getRightClicked().getType()) {
- case MUSHROOM_COW:
- case SHEEP:
- case SNOWMAN:
- Slimefun.getLocalization().sendMessage(e.getPlayer(), "messages.multi-tool.not-shears");
- e.setCancelled(true);
- break;
- default:
- break;
+ EntityType type = e.getRightClicked().getType();
+ if (type == VersionedEntityType.MOOSHROOM
+ || type == VersionedEntityType.SNOW_GOLEM
+ || type == EntityType.SHEEP
+ ) {
+ Slimefun.getLocalization().sendMessage(e.getPlayer(), "messages.multi-tool.not-shears");
+ e.setCancelled(true);
}
};
}
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/gadgets/MultiToolMode.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/gadgets/MultiToolMode.java
index 7bf079771b..d3963496d4 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/gadgets/MultiToolMode.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/gadgets/MultiToolMode.java
@@ -8,22 +8,43 @@
class MultiToolMode {
+ private final int id;
+ private final String itemId;
private final ItemSetting item;
private final ItemSetting enabled;
+ // TODO: Move "id" into some NamespacedKey
MultiToolMode(@Nonnull MultiTool multiTool, int id, @Nonnull String itemId) {
+ this.id = id;
+ this.itemId = itemId;
this.item = new ItemSetting<>(multiTool, "mode." + id + ".item", itemId);
this.enabled = new ItemSetting<>(multiTool, "mode." + id + ".enabled", true);
multiTool.addItemSetting(item, enabled);
}
+ /**
+ * This method is deprecated and should not be used.
+ *
+ *
+ * @return The ID of this mode
+ */
+ @Deprecated(since = "RC-37", forRemoval = true)
+ public int getId() {
+ return id;
+ }
+
@Nullable
SlimefunItem getItem() {
return SlimefunItem.getById(item.getValue());
}
+ @Nonnull
+ String getItemId() {
+ return itemId;
+ }
+
boolean isEnabled() {
return enabled.getValue();
}
-}
+}
\ No newline at end of file
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/AutoBrewer.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/AutoBrewer.java
index f00676edd6..962bc2d32f 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/AutoBrewer.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/AutoBrewer.java
@@ -7,6 +7,7 @@
import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
+import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.PotionMeta;
@@ -18,7 +19,7 @@
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
import io.github.thebusybiscuit.slimefun4.core.attributes.NotHopperable;
-
+import io.github.thebusybiscuit.slimefun4.utils.compatibility.VersionedPotionType;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AContainer;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.MachineRecipe;
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu;
@@ -36,22 +37,22 @@ public class AutoBrewer extends AContainer implements NotHopperable {
private static final Map fermentations = new EnumMap<>(PotionType.class);
static {
- potionRecipes.put(Material.SUGAR, PotionType.SPEED);
- potionRecipes.put(Material.RABBIT_FOOT, PotionType.JUMP);
+ potionRecipes.put(Material.SUGAR, VersionedPotionType.SWIFTNESS);
+ potionRecipes.put(Material.RABBIT_FOOT, VersionedPotionType.LEAPING);
potionRecipes.put(Material.BLAZE_POWDER, PotionType.STRENGTH);
- potionRecipes.put(Material.GLISTERING_MELON_SLICE, PotionType.INSTANT_HEAL);
+ potionRecipes.put(Material.GLISTERING_MELON_SLICE, VersionedPotionType.HEALING);
potionRecipes.put(Material.SPIDER_EYE, PotionType.POISON);
- potionRecipes.put(Material.GHAST_TEAR, PotionType.REGEN);
+ potionRecipes.put(Material.GHAST_TEAR, VersionedPotionType.REGENERATION);
potionRecipes.put(Material.MAGMA_CREAM, PotionType.FIRE_RESISTANCE);
potionRecipes.put(Material.PUFFERFISH, PotionType.WATER_BREATHING);
potionRecipes.put(Material.GOLDEN_CARROT, PotionType.NIGHT_VISION);
potionRecipes.put(Material.TURTLE_HELMET, PotionType.TURTLE_MASTER);
potionRecipes.put(Material.PHANTOM_MEMBRANE, PotionType.SLOW_FALLING);
- fermentations.put(PotionType.SPEED, PotionType.SLOWNESS);
- fermentations.put(PotionType.JUMP, PotionType.SLOWNESS);
- fermentations.put(PotionType.INSTANT_HEAL, PotionType.INSTANT_DAMAGE);
- fermentations.put(PotionType.POISON, PotionType.INSTANT_DAMAGE);
+ fermentations.put(VersionedPotionType.SWIFTNESS, PotionType.SLOWNESS);
+ fermentations.put(VersionedPotionType.LEAPING, PotionType.SLOWNESS);
+ fermentations.put(VersionedPotionType.HEALING, VersionedPotionType.HARMING);
+ fermentations.put(PotionType.POISON, VersionedPotionType.HARMING);
fermentations.put(PotionType.NIGHT_VISION, PotionType.INVISIBILITY);
}
@@ -104,8 +105,53 @@ public AutoBrewer(ItemGroup itemGroup, SlimefunItemStack item, RecipeType recipe
@ParametersAreNonnullByDefault
private @Nullable ItemStack brew(Material input, Material potionType, PotionMeta potion) {
- PotionData data = potion.getBasePotionData();
+ if (Slimefun.getMinecraftVersion().isBefore(20,2)) {
+ return brewPreBasePotionType(input, potionType, potion);
+ }
+ PotionType type = potion.getBasePotionType();
+ if (type == PotionType.WATER) {
+ if (input == Material.FERMENTED_SPIDER_EYE) {
+ potion.setBasePotionType(PotionType.WEAKNESS);
+ return new ItemStack(potionType);
+ } else if (input == Material.NETHER_WART) {
+ potion.setBasePotionType(PotionType.AWKWARD);
+ return new ItemStack(potionType);
+ } else if (potionType == Material.POTION && input == Material.GUNPOWDER) {
+ return new ItemStack(Material.SPLASH_POTION);
+ } else if (potionType == Material.SPLASH_POTION && input == Material.DRAGON_BREATH) {
+ return new ItemStack(Material.LINGERING_POTION);
+ }
+ } else if (input == Material.FERMENTED_SPIDER_EYE) {
+ PotionType fermented = fermentations.get(type);
+
+ if (fermented != null) {
+ potion.setBasePotionType(fermented);
+ return new ItemStack(potionType);
+ }
+ } else if (input == Material.REDSTONE && type.isExtendable() && !type.isUpgradeable()) {
+ // Fixes #3390 - Potions can only be either extended or upgraded. Not both.
+ potion.setBasePotionType(type);
+ return new ItemStack(potionType);
+ } else if (input == Material.GLOWSTONE_DUST && type.isUpgradeable() && !type.isExtendable()) {
+ // Fixes #3390 - Potions can only be either extended or upgraded. Not both.
+ potion.setBasePotionType(type);
+ return new ItemStack(potionType);
+ } else if (type == PotionType.AWKWARD) {
+ PotionType potionRecipe = potionRecipes.get(input);
+
+ if (potionRecipe != null) {
+ potion.setBasePotionType(potionRecipe);
+ return new ItemStack(potionType);
+ }
+ }
+ return null;
+ }
+
+ @ParametersAreNonnullByDefault
+ @SuppressWarnings("deprecration")
+ private ItemStack brewPreBasePotionType(Material input, Material potionType, PotionMeta potion) {
+ PotionData data = potion.getBasePotionData();
PotionType type = data.getType();
if (type == PotionType.WATER) {
if (input == Material.FERMENTED_SPIDER_EYE) {
@@ -142,16 +188,15 @@ public AutoBrewer(ItemGroup itemGroup, SlimefunItemStack item, RecipeType recipe
return new ItemStack(potionType);
}
}
-
return null;
}
/**
* Checks whether a given {@link Material} is a valid Potion material.
- *
+ *
* @param mat
* The {@link Material} to check
- *
+ *
* @return Whether this {@link Material} is a valid potion
*/
private boolean isPotion(@Nonnull Material mat) {
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/ChargingBench.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/ChargingBench.java
index e3395e9f64..b535e44b40 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/ChargingBench.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/ChargingBench.java
@@ -44,6 +44,10 @@ protected void tick(Block b) {
for (int slot : getInputSlots()) {
ItemStack item = inv.getItemInSlot(slot);
+ if (item == null || item.getAmount() != 1) {
+ continue;
+ }
+
if (charge(b, inv, slot, item)) {
return;
}
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/ElectricSmeltery.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/ElectricSmeltery.java
index 24e0e0c33e..2218339998 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/ElectricSmeltery.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/ElectricSmeltery.java
@@ -11,7 +11,6 @@
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
-import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.ItemStack;
import io.github.bakedlibs.dough.items.CustomItemStack;
@@ -25,8 +24,6 @@
import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils;
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
-import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu.AdvancedMenuClickHandler;
-import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ClickAction;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AContainer;
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset;
import me.mrCookieSlime.Slimefun.api.inventory.DirtyChestMenu;
@@ -126,18 +123,7 @@ protected void constructMenu(BlockMenuPreset preset) {
preset.addItem(22, new CustomItemStack(Material.BLACK_STAINED_GLASS_PANE, " "), ChestMenuUtils.getEmptyClickHandler());
for (int i : getOutputSlots()) {
- preset.addMenuClickHandler(i, new AdvancedMenuClickHandler() {
-
- @Override
- public boolean onClick(Player p, int slot, ItemStack cursor, ClickAction action) {
- return false;
- }
-
- @Override
- public boolean onClick(InventoryClickEvent e, Player p, int slot, ItemStack cursor, ClickAction action) {
- return cursor == null || cursor.getType() == null || cursor.getType() == Material.AIR;
- }
- });
+ preset.addMenuClickHandler(i, ChestMenuUtils.getDefaultOutputHandler());
}
}
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/FluidPump.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/FluidPump.java
index b0bfacd9de..729fd2ff51 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/FluidPump.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/FluidPump.java
@@ -7,14 +7,13 @@
import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
+import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.Levelled;
-import org.bukkit.entity.Player;
-import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.ItemStack;
import io.github.bakedlibs.dough.blocks.Vein;
@@ -32,8 +31,6 @@
import io.github.thebusybiscuit.slimefun4.utils.itemstack.ItemStackWrapper;
import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config;
-import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu.AdvancedMenuClickHandler;
-import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ClickAction;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.interfaces.InventoryBlock;
import me.mrCookieSlime.Slimefun.Objects.handlers.BlockTicker;
import me.mrCookieSlime.Slimefun.api.BlockStorage;
@@ -100,18 +97,7 @@ private void constructMenu(@Nonnull BlockMenuPreset preset) {
}
for (int i : getOutputSlots()) {
- preset.addMenuClickHandler(i, new AdvancedMenuClickHandler() {
-
- @Override
- public boolean onClick(Player p, int slot, ItemStack cursor, ClickAction action) {
- return false;
- }
-
- @Override
- public boolean onClick(InventoryClickEvent e, Player p, int slot, ItemStack cursor, ClickAction action) {
- return cursor == null || cursor.getType() == null || cursor.getType() == Material.AIR;
- }
- });
+ preset.addMenuClickHandler(i, ChestMenuUtils.getDefaultOutputHandler());
}
}
@@ -218,7 +204,11 @@ private Block findNextFluid(@Nonnull Block fluid) {
case BUBBLE_COLUMN:
ItemStack waterBottle = new ItemStack(Material.POTION);
PotionMeta meta = (PotionMeta) waterBottle.getItemMeta();
- meta.setBasePotionData(new PotionData(PotionType.WATER));
+ if (Slimefun.getMinecraftVersion().isBefore(20, 2)) {
+ meta.setBasePotionData(new PotionData(PotionType.WATER));
+ } else {
+ meta.setBasePotionType(PotionType.WATER);
+ }
waterBottle.setItemMeta(meta);
return waterBottle;
default:
@@ -239,10 +229,10 @@ private Block findNextFluid(@Nonnull Block fluid) {
/**
* This method checks if the given {@link Block} is a liquid source {@link Block}.
- *
+ *
* @param block
* The {@link Block} in question
- *
+ *
* @return Whether that {@link Block} is a liquid and a source {@link Block}.
*/
private boolean isSource(@Nonnull Block block) {
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/accelerators/AnimalGrowthAccelerator.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/accelerators/AnimalGrowthAccelerator.java
index 68a570f8a5..1da903c425 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/accelerators/AnimalGrowthAccelerator.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/accelerators/AnimalGrowthAccelerator.java
@@ -1,6 +1,5 @@
package io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.accelerators;
-import org.bukkit.Particle;
import org.bukkit.block.Block;
import org.bukkit.entity.Ageable;
import org.bukkit.entity.Entity;
@@ -12,6 +11,7 @@
import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
+import io.github.thebusybiscuit.slimefun4.utils.compatibility.VersionedParticle;
import io.github.thebusybiscuit.slimefun4.utils.itemstack.ItemStackWrapper;
import me.mrCookieSlime.Slimefun.api.BlockStorage;
@@ -54,7 +54,7 @@ protected void tick(Block b) {
ageable.setAge(0);
}
- n.getWorld().spawnParticle(Particle.VILLAGER_HAPPY, ((LivingEntity) n).getEyeLocation(), 8, 0.2F, 0.2F, 0.2F);
+ n.getWorld().spawnParticle(VersionedParticle.HAPPY_VILLAGER, ((LivingEntity) n).getEyeLocation(), 8, 0.2F, 0.2F, 0.2F);
return;
}
}
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/accelerators/CropGrowthAccelerator.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/accelerators/CropGrowthAccelerator.java
index 5649c70c73..5cf09b31f9 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/accelerators/CropGrowthAccelerator.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/accelerators/CropGrowthAccelerator.java
@@ -1,6 +1,5 @@
package io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.accelerators;
-import org.bukkit.Particle;
import org.bukkit.block.Block;
import org.bukkit.block.data.Ageable;
import org.bukkit.inventory.ItemStack;
@@ -10,6 +9,7 @@
import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
+import io.github.thebusybiscuit.slimefun4.utils.compatibility.VersionedParticle;
import io.github.thebusybiscuit.slimefun4.utils.itemstack.ItemStackWrapper;
import io.github.thebusybiscuit.slimefun4.utils.tags.SlimefunTag;
@@ -65,7 +65,7 @@ private boolean grow(Block machine, BlockMenu inv, Block crop) {
ageable.setAge(ageable.getAge() + 1);
crop.setBlockData(ageable);
- crop.getWorld().spawnParticle(Particle.VILLAGER_HAPPY, crop.getLocation().add(0.5D, 0.5D, 0.5D), 4, 0.1F, 0.1F, 0.1F);
+ crop.getWorld().spawnParticle(VersionedParticle.HAPPY_VILLAGER, crop.getLocation().add(0.5D, 0.5D, 0.5D), 4, 0.1F, 0.1F, 0.1F);
return true;
}
}
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/accelerators/TreeGrowthAccelerator.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/accelerators/TreeGrowthAccelerator.java
index e6e79311db..a9332d777e 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/accelerators/TreeGrowthAccelerator.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/accelerators/TreeGrowthAccelerator.java
@@ -4,7 +4,6 @@
import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
-import org.bukkit.Particle;
import org.bukkit.Tag;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
@@ -18,6 +17,7 @@
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
+import io.github.thebusybiscuit.slimefun4.utils.compatibility.VersionedParticle;
import io.github.thebusybiscuit.slimefun4.utils.itemstack.ItemStackWrapper;
import me.mrCookieSlime.Slimefun.api.BlockStorage;
@@ -93,7 +93,7 @@ private boolean applyBoneMeal(Block machine, Block sapling, BlockMenu inv) {
sapling.applyBoneMeal(BlockFace.UP);
inv.consumeItem(slot);
- sapling.getWorld().spawnParticle(Particle.VILLAGER_HAPPY, sapling.getLocation().add(0.5D, 0.5D, 0.5D), 4, 0.1F, 0.1F, 0.1F);
+ sapling.getWorld().spawnParticle(VersionedParticle.HAPPY_VILLAGER, sapling.getLocation().add(0.5D, 0.5D, 0.5D), 4, 0.1F, 0.1F, 0.1F);
return true;
}
}
@@ -111,7 +111,7 @@ private boolean updateSaplingData(Block machine, Block block, BlockMenu inv, Sap
block.setBlockData(sapling, false);
inv.consumeItem(slot);
- block.getWorld().spawnParticle(Particle.VILLAGER_HAPPY, block.getLocation().add(0.5D, 0.5D, 0.5D), 4, 0.1F, 0.1F, 0.1F);
+ block.getWorld().spawnParticle(VersionedParticle.HAPPY_VILLAGER, block.getLocation().add(0.5D, 0.5D, 0.5D), 4, 0.1F, 0.1F, 0.1F);
return true;
}
}
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/entities/ExpCollector.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/entities/ExpCollector.java
index 3a6cb6d857..4697ec75fd 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/entities/ExpCollector.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/entities/ExpCollector.java
@@ -44,35 +44,43 @@ public class ExpCollector extends SlimefunItem implements InventoryBlock, Energy
private final int[] border = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26 };
- private static final int ENERGY_CONSUMPTION = 10;
private static final String DATA_KEY = "stored-exp";
+ private final double range;
+ private int energyConsumedPerTick = -1;
+ private int energyCapacity = -1;
+
+ @Deprecated(since = "RC-38", forRemoval = true)
@ParametersAreNonnullByDefault
public ExpCollector(ItemGroup itemGroup, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
+ this(itemGroup, item, recipeType, recipe, 4.0);
+ }
+
+ @ParametersAreNonnullByDefault
+ public ExpCollector(ItemGroup itemGroup, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe, double range) {
super(itemGroup, item, recipeType, recipe);
+ this.range = range;
createPreset(this, this::constructMenu);
-
addItemHandler(onPlace(), onBreak());
}
- @Nonnull
- private BlockPlaceHandler onPlace() {
+
+ private @Nonnull BlockPlaceHandler onPlace() {
return new BlockPlaceHandler(false) {
@Override
- public void onPlayerPlace(BlockPlaceEvent e) {
+ public void onPlayerPlace(@Nonnull BlockPlaceEvent e) {
BlockStorage.addBlockInfo(e.getBlock(), "owner", e.getPlayer().getUniqueId().toString());
}
};
}
- @Nonnull
- private ItemHandler onBreak() {
+ private @Nonnull ItemHandler onBreak() {
return new SimpleBlockBreakHandler() {
@Override
- public void onBlockBreak(Block b) {
+ public void onBlockBreak(@Nonnull Block b) {
BlockMenu inv = BlockStorage.getInventory(b);
if (inv != null) {
@@ -97,11 +105,6 @@ public EnergyNetComponentType getEnergyComponentType() {
return EnergyNetComponentType.CONSUMER;
}
- @Override
- public int getCapacity() {
- return 1024;
- }
-
protected void constructMenu(BlockMenuPreset preset) {
for (int slot : border) {
preset.addItem(slot, new CustomItemStack(Material.PURPLE_STAINED_GLASS_PANE, " "), (p, s, item, action) -> false);
@@ -126,19 +129,19 @@ public boolean isSynchronized() {
protected void tick(Block block) {
Location location = block.getLocation();
- Iterator iterator = block.getWorld().getNearbyEntities(location, 4.0, 4.0, 4.0, n -> n instanceof ExperienceOrb && n.isValid()).iterator();
+ Iterator iterator = block.getWorld().getNearbyEntities(location, range, range, range, n -> n instanceof ExperienceOrb && n.isValid()).iterator();
int experiencePoints = 0;
while (iterator.hasNext() && experiencePoints == 0) {
ExperienceOrb orb = (ExperienceOrb) iterator.next();
- if (getCharge(location) < ENERGY_CONSUMPTION) {
+ if (getCharge(location) < getEnergyConsumption()) {
return;
}
experiencePoints = getStoredExperience(location) + orb.getExperience();
- removeCharge(location, ENERGY_CONSUMPTION);
+ removeCharge(location, getEnergyConsumption());
orb.remove();
produceFlasks(location, experiencePoints);
}
@@ -179,4 +182,23 @@ private int getStoredExperience(Location location) {
return 0;
}
}
+
+ public int getEnergyConsumption() {
+ return energyConsumedPerTick;
+ }
+
+ public ExpCollector setEnergyConsumption(int energyConsumedPerTick) {
+ this.energyConsumedPerTick = energyConsumedPerTick;
+ return this;
+ }
+
+ @Override
+ public int getCapacity() {
+ return energyCapacity;
+ }
+
+ public ExpCollector setCapacity(int energyCapacity) {
+ this.energyCapacity = energyCapacity;
+ return this;
+ }
}
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/geo/GEOMiner.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/geo/GEOMiner.java
index cc09eb0ac6..d21815533b 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/geo/GEOMiner.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/geo/GEOMiner.java
@@ -11,9 +11,7 @@
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.block.Block;
-import org.bukkit.entity.Player;
import org.bukkit.event.block.BlockPlaceEvent;
-import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.ItemStack;
import io.github.bakedlibs.dough.items.CustomItemStack;
@@ -38,8 +36,6 @@
import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils;
import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config;
-import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu.AdvancedMenuClickHandler;
-import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ClickAction;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.interfaces.InventoryBlock;
import me.mrCookieSlime.Slimefun.Objects.handlers.BlockTicker;
import me.mrCookieSlime.Slimefun.api.BlockStorage;
@@ -265,18 +261,7 @@ protected void constructMenu(@Nonnull BlockMenuPreset preset) {
preset.addItem(4, new CustomItemStack(Material.BLACK_STAINED_GLASS_PANE, " "), ChestMenuUtils.getEmptyClickHandler());
for (int i : OUTPUT_SLOTS) {
- preset.addMenuClickHandler(i, new AdvancedMenuClickHandler() {
-
- @Override
- public boolean onClick(Player p, int slot, ItemStack cursor, ClickAction action) {
- return false;
- }
-
- @Override
- public boolean onClick(InventoryClickEvent e, Player p, int slot, ItemStack cursor, ClickAction action) {
- return cursor == null || cursor.getType() == null || cursor.getType() == Material.AIR;
- }
- });
+ preset.addMenuClickHandler(i, ChestMenuUtils.getDefaultOutputHandler());
}
}
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/magical/runes/EnchantmentRune.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/magical/runes/EnchantmentRune.java
index ce8e53f8d9..33e54e7544 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/magical/runes/EnchantmentRune.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/magical/runes/EnchantmentRune.java
@@ -14,7 +14,6 @@
import org.bukkit.Location;
import org.bukkit.Material;
-import org.bukkit.Particle;
import org.bukkit.SoundCategory;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Entity;
@@ -30,6 +29,7 @@
import io.github.thebusybiscuit.slimefun4.core.services.sounds.SoundEffect;
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
+import io.github.thebusybiscuit.slimefun4.utils.compatibility.VersionedParticle;
/**
* This {@link SlimefunItem} allows you to enchant any enchantable {@link ItemStack} with a random
@@ -50,6 +50,8 @@ public EnchantmentRune(ItemGroup itemGroup, SlimefunItemStack item, RecipeType r
super(itemGroup, item, recipeType, recipe);
for (Material mat : Material.values()) {
+ if (Slimefun.instance().isUnitTest() && mat.isLegacy()) continue;
+
List enchantments = new ArrayList<>();
for (Enchantment enchantment : Enchantment.values()) {
@@ -140,7 +142,7 @@ private void addRandomEnchantment(@Nonnull Player p, @Nonnull Item rune) {
// Being sure entities are still valid and not picked up or whatsoever.
if (rune.isValid() && item.isValid() && itemStack.getAmount() == 1) {
- l.getWorld().spawnParticle(Particle.CRIT_MAGIC, l, 1);
+ l.getWorld().spawnParticle(VersionedParticle.ENCHANTED_HIT, l, 1);
SoundEffect.ENCHANTMENT_RUNE_ADD_ENCHANT_SOUND.playAt(l, SoundCategory.PLAYERS);
item.remove();
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/magical/runes/VillagerRune.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/magical/runes/VillagerRune.java
index d5a3b325aa..fe5195e22c 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/magical/runes/VillagerRune.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/magical/runes/VillagerRune.java
@@ -22,6 +22,7 @@
import io.github.thebusybiscuit.slimefun4.core.services.sounds.SoundEffect;
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
+import io.github.thebusybiscuit.slimefun4.utils.compatibility.VersionedParticle;
/**
* This {@link SlimefunItem} allows you to reset a {@link Villager} profession.
@@ -64,7 +65,7 @@ public VillagerRune(ItemGroup itemGroup, SlimefunItemStack item, RecipeType reci
SoundEffect.VILLAGER_RUNE_TRANSFORM_SOUND.playAt(villager.getLocation(), SoundCategory.NEUTRAL);
villager.getWorld().spawnParticle(Particle.CRIMSON_SPORE, villager.getLocation(), 10, 0, offset / 2, 0, 0);
- villager.getWorld().spawnParticle(Particle.ENCHANTMENT_TABLE, villager.getLocation(), 5, 0.04, 1, 0.04);
+ villager.getWorld().spawnParticle(VersionedParticle.ENCHANT, villager.getLocation(), 5, 0.04, 1, 0.04);
}
};
}
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/medical/Bandage.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/medical/Bandage.java
index d69ceeaa91..b87882cf6d 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/medical/Bandage.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/medical/Bandage.java
@@ -9,7 +9,6 @@
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.potion.PotionEffect;
-import org.bukkit.potion.PotionEffectType;
import io.github.bakedlibs.dough.items.ItemUtils;
import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup;
@@ -17,6 +16,7 @@
import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
import io.github.thebusybiscuit.slimefun4.core.handlers.ItemUseHandler;
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
+import io.github.thebusybiscuit.slimefun4.utils.compatibility.VersionedPotionEffectType;
/**
* A {@link Bandage} or Rag is a medical supply which heals the {@link Player} and extinguishes
@@ -51,7 +51,7 @@ public ItemUseHandler getItemHandler() {
}
p.getWorld().playEffect(p.getLocation(), Effect.STEP_SOUND, Material.WHITE_WOOL);
- p.addPotionEffect(new PotionEffect(PotionEffectType.HEAL, 1, healingLevel));
+ p.addPotionEffect(new PotionEffect(VersionedPotionEffectType.INSTANT_HEALTH, 1, healingLevel));
p.setFireTicks(0);
e.cancel();
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/medical/MedicalSupply.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/medical/MedicalSupply.java
index 2a0383001b..350376eab8 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/medical/MedicalSupply.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/medical/MedicalSupply.java
@@ -18,6 +18,7 @@
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
+import io.github.thebusybiscuit.slimefun4.utils.compatibility.VersionedPotionEffectType;
public abstract class MedicalSupply extends SimpleSlimefunItem {
@@ -32,10 +33,10 @@ protected MedicalSupply(ItemGroup itemGroup, int healAmount, SlimefunItemStack i
curedEffects.add(PotionEffectType.POISON);
curedEffects.add(PotionEffectType.WITHER);
- curedEffects.add(PotionEffectType.SLOW);
- curedEffects.add(PotionEffectType.SLOW_DIGGING);
+ curedEffects.add(VersionedPotionEffectType.SLOWNESS);
+ curedEffects.add(VersionedPotionEffectType.MINING_FATIGUE);
curedEffects.add(PotionEffectType.WEAKNESS);
- curedEffects.add(PotionEffectType.CONFUSION);
+ curedEffects.add(VersionedPotionEffectType.NAUSEA);
curedEffects.add(PotionEffectType.BLINDNESS);
curedEffects.add(PotionEffectType.BAD_OMEN);
}
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/medical/Splint.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/medical/Splint.java
index a6495d061a..0a510ff28a 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/medical/Splint.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/medical/Splint.java
@@ -8,7 +8,6 @@
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.potion.PotionEffect;
-import org.bukkit.potion.PotionEffectType;
import io.github.bakedlibs.dough.items.ItemUtils;
import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup;
@@ -17,6 +16,7 @@
import io.github.thebusybiscuit.slimefun4.core.handlers.ItemUseHandler;
import io.github.thebusybiscuit.slimefun4.core.services.sounds.SoundEffect;
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
+import io.github.thebusybiscuit.slimefun4.utils.compatibility.VersionedPotionEffectType;
public class Splint extends SimpleSlimefunItem {
@@ -40,7 +40,7 @@ public Splint(ItemGroup itemGroup, SlimefunItemStack item, RecipeType recipeType
}
SoundEffect.SPLINT_CONSUME_SOUND.playFor(p);
- p.addPotionEffect(new PotionEffect(PotionEffectType.HEAL, 1, 0));
+ p.addPotionEffect(new PotionEffect(VersionedPotionEffectType.INSTANT_HEALTH, 1, 0));
e.cancel();
};
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/miner/MiningTask.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/miner/MiningTask.java
index 5da4697970..0169f0f846 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/miner/MiningTask.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/miner/MiningTask.java
@@ -10,7 +10,6 @@
import org.bukkit.Effect;
import org.bukkit.Location;
import org.bukkit.Material;
-import org.bukkit.Particle;
import org.bukkit.Sound;
import org.bukkit.World;
import org.bukkit.block.Block;
@@ -30,6 +29,7 @@
import io.github.bakedlibs.dough.scheduling.TaskQueue;
import io.github.thebusybiscuit.slimefun4.core.services.sounds.SoundEffect;
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
+import io.github.thebusybiscuit.slimefun4.utils.compatibility.VersionedParticle;
import io.papermc.lib.PaperLib;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.MachineFuel;
@@ -341,7 +341,7 @@ private void setPistonState(@Nonnull Block block, boolean extended) {
try {
// Smoke Particles around the Chest for dramatic effect
Location particleLoc = chest.getLocation().clone().add(0, -1, 0);
- block.getWorld().spawnParticle(Particle.SMOKE_NORMAL, particleLoc, 20, 0.7, 0.7, 0.7, 0);
+ block.getWorld().spawnParticle(VersionedParticle.SMOKE, particleLoc, 20, 0.7, 0.7, 0.7, 0);
if (block.getType() == Material.MOVING_PISTON) {
// Yeah it isn't really cool when this happens
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/ClimbingPick.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/ClimbingPick.java
index 43f0225237..265db240ed 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/ClimbingPick.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/ClimbingPick.java
@@ -39,6 +39,7 @@
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
import io.github.thebusybiscuit.slimefun4.implementation.settings.ClimbableSurface;
+import io.github.thebusybiscuit.slimefun4.utils.compatibility.VersionedEnchantment;
import io.github.thebusybiscuit.slimefun4.utils.tags.SlimefunTag;
/**
@@ -147,7 +148,7 @@ public double getClimbingSpeed(@Nonnull ItemStack item, @Nonnull Material type)
double speed = getClimbingSpeed(type);
if (speed > 0) {
- int efficiencyLevel = item.getEnchantmentLevel(Enchantment.DIG_SPEED);
+ int efficiencyLevel = item.getEnchantmentLevel(VersionedEnchantment.EFFICIENCY);
if (efficiencyLevel > 0) {
speed += efficiencyLevel * EFFICIENCY_MODIFIER;
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/weapons/ExplosiveBow.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/weapons/ExplosiveBow.java
index d4cea025f5..1477549c9f 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/weapons/ExplosiveBow.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/weapons/ExplosiveBow.java
@@ -6,7 +6,6 @@
import javax.annotation.ParametersAreNonnullByDefault;
import org.bukkit.Bukkit;
-import org.bukkit.Particle;
import org.bukkit.SoundCategory;
import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.Entity;
@@ -22,6 +21,7 @@
import io.github.thebusybiscuit.slimefun4.api.items.settings.IntRangeSetting;
import io.github.thebusybiscuit.slimefun4.core.handlers.BowShootHandler;
import io.github.thebusybiscuit.slimefun4.core.services.sounds.SoundEffect;
+import io.github.thebusybiscuit.slimefun4.utils.compatibility.VersionedParticle;
/**
* The {@link ExplosiveBow} is a {@link SlimefunBow} which creates a fake explosion when it hits
@@ -49,7 +49,7 @@ public ExplosiveBow(ItemGroup itemGroup, SlimefunItemStack item, ItemStack[] rec
@Override
public BowShootHandler onShoot() {
return (e, target) -> {
- target.getWorld().spawnParticle(Particle.EXPLOSION_LARGE, target.getLocation(), 1);
+ target.getWorld().spawnParticle(VersionedParticle.EXPLOSION, target.getLocation(), 1);
SoundEffect.EXPLOSIVE_BOW_HIT_SOUND.playAt(target.getLocation(), SoundCategory.PLAYERS);
int radius = range.getValue();
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/weapons/IcyBow.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/weapons/IcyBow.java
index 474a7277d6..b3e54f15ed 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/weapons/IcyBow.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/weapons/IcyBow.java
@@ -9,13 +9,13 @@
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.potion.PotionEffect;
-import org.bukkit.potion.PotionEffectType;
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup;
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
import io.github.thebusybiscuit.slimefun4.core.handlers.BowShootHandler;
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
+import io.github.thebusybiscuit.slimefun4.utils.compatibility.VersionedPotionEffectType;
/**
* The {@link IcyBow} is a special kind of bow which slows down any
@@ -48,8 +48,8 @@ public BowShootHandler onShoot() {
}
n.getWorld().playEffect(n.getLocation(), Effect.STEP_SOUND, Material.ICE);
n.getWorld().playEffect(n.getEyeLocation(), Effect.STEP_SOUND, Material.ICE);
- n.addPotionEffect(new PotionEffect(PotionEffectType.SLOW, 20 * 2, 10));
- n.addPotionEffect(new PotionEffect(PotionEffectType.JUMP, 20 * 2, -10));
+ n.addPotionEffect(new PotionEffect(VersionedPotionEffectType.SLOWNESS, 20 * 2, 10));
+ n.addPotionEffect(new PotionEffect(VersionedPotionEffectType.JUMP_BOOST, 20 * 2, -10));
};
}
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/BlockListener.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/BlockListener.java
index 12937e45a4..40b976e345 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/BlockListener.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/BlockListener.java
@@ -39,6 +39,7 @@
import io.github.thebusybiscuit.slimefun4.core.handlers.BlockPlaceHandler;
import io.github.thebusybiscuit.slimefun4.core.handlers.ToolUseHandler;
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
+import io.github.thebusybiscuit.slimefun4.utils.compatibility.VersionedEnchantment;
import io.github.thebusybiscuit.slimefun4.utils.tags.SlimefunTag;
import me.mrCookieSlime.Slimefun.api.BlockStorage;
@@ -70,18 +71,18 @@ public void onBlockPlaceExisting(BlockPlaceEvent e) {
Block block = e.getBlock();
// Fixes #2636 - This will solve the "ghost blocks" issue
- if (e.getBlockReplacedState().getType().isAir()) {
+ if (e.getBlockReplacedState().getType().isAir() && BlockStorage.hasBlockInfo(block) && !Slimefun.getTickerTask().isDeletedSoon(block.getLocation())) {
SlimefunItem sfItem = BlockStorage.check(block);
- if (sfItem != null && !Slimefun.getTickerTask().isDeletedSoon(block.getLocation())) {
+ if (sfItem != null) {
for (ItemStack item : sfItem.getDrops()) {
if (item != null && !item.getType().isAir()) {
block.getWorld().dropItemNaturally(block.getLocation(), item);
}
}
-
- BlockStorage.clearBlockInfo(block);
}
+
+ BlockStorage.clearBlockInfo(block);
} else if (BlockStorage.hasBlockInfo(e.getBlock())) {
// If there is no air (e.g. grass) then don't let the block be placed
e.setCancelled(true);
@@ -374,7 +375,7 @@ private int getBonusDropsWithFortune(@Nullable ItemStack item, @Nonnull Block b)
* directly and re use it.
*/
ItemMeta meta = item.getItemMeta();
- int fortuneLevel = meta.getEnchantLevel(Enchantment.LOOT_BONUS_BLOCKS);
+ int fortuneLevel = meta.getEnchantLevel(VersionedEnchantment.FORTUNE);
if (fortuneLevel > 0 && !meta.hasEnchant(Enchantment.SILK_TOUCH)) {
Random random = ThreadLocalRandom.current();
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TalismanListener.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TalismanListener.java
index a01625c836..7a8b29c0df 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TalismanListener.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TalismanListener.java
@@ -49,6 +49,7 @@
import io.github.thebusybiscuit.slimefun4.implementation.items.magical.talismans.MagicianTalisman;
import io.github.thebusybiscuit.slimefun4.implementation.items.magical.talismans.Talisman;
import io.github.thebusybiscuit.slimefun4.implementation.settings.TalismanEnchantment;
+import io.github.thebusybiscuit.slimefun4.utils.compatibility.VersionedEnchantment;
import io.github.thebusybiscuit.slimefun4.utils.tags.SlimefunTag;
/**
@@ -301,7 +302,7 @@ public void onEnchant(EnchantItemEvent e) {
}
// Wizard Talisman
- if (!enchantments.containsKey(Enchantment.SILK_TOUCH) && Enchantment.LOOT_BONUS_BLOCKS.canEnchantItem(e.getItem()) && Talisman.trigger(e, SlimefunItems.TALISMAN_WIZARD)) {
+ if (!enchantments.containsKey(Enchantment.SILK_TOUCH) && VersionedEnchantment.FORTUNE.canEnchantItem(e.getItem()) && Talisman.trigger(e, SlimefunItems.TALISMAN_WIZARD)) {
// Randomly lower some enchantments
for (Map.Entry entry : enchantments.entrySet()) {
if (entry.getValue() > 1 && random.nextInt(100) < 40) {
@@ -310,7 +311,7 @@ public void onEnchant(EnchantItemEvent e) {
}
// Give an extra Fortune boost (Lvl 3 - 5)
- enchantments.put(Enchantment.LOOT_BONUS_BLOCKS, random.nextInt(3) + 3);
+ enchantments.put(VersionedEnchantment.FORTUNE, random.nextInt(3) + 3);
}
}
@@ -351,7 +352,7 @@ private void doubleTalismanDrops(BlockDropItemEvent e, SlimefunItemStack talisma
Collection- drops = e.getItems();
if (Talisman.trigger(e, talismanItemStack, false)) {
- int dropAmount = getAmountWithFortune(type, meta.getEnchantLevel(Enchantment.LOOT_BONUS_BLOCKS));
+ int dropAmount = getAmountWithFortune(type, meta.getEnchantLevel(VersionedEnchantment.FORTUNE));
// Keep track of whether we actually doubled the drops or not
boolean doubledDrops = false;
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/setup/SlimefunItemSetup.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/setup/SlimefunItemSetup.java
index 9ade30e843..14575310af 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/setup/SlimefunItemSetup.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/setup/SlimefunItemSetup.java
@@ -217,6 +217,7 @@
import io.github.thebusybiscuit.slimefun4.utils.ColoredMaterial;
import io.github.thebusybiscuit.slimefun4.utils.HeadTexture;
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
+import io.github.thebusybiscuit.slimefun4.utils.compatibility.VersionedPotionEffectType;
/**
* This class holds the recipes of all items.
@@ -241,7 +242,7 @@ public static void setup(@Nonnull Slimefun plugin) {
new SlimefunItem(itemGroups.weapons, SlimefunItems.GRANDMAS_WALKING_STICK, RecipeType.ENHANCED_CRAFTING_TABLE,
new ItemStack[] {null, new ItemStack(Material.OAK_LOG), null, null, new ItemStack(Material.OAK_LOG), null, null, new ItemStack(Material.OAK_LOG), null})
.register(plugin);
-
+
new SlimefunItem(itemGroups.weapons, SlimefunItems.GRANDPAS_WALKING_STICK, RecipeType.ENHANCED_CRAFTING_TABLE,
new ItemStack[] {new ItemStack(Material.LEATHER), new ItemStack(Material.OAK_LOG), new ItemStack(Material.LEATHER), null, new ItemStack(Material.OAK_LOG), null, null, new ItemStack(Material.OAK_LOG), null})
.register(plugin);
@@ -261,7 +262,7 @@ public static void setup(@Nonnull Slimefun plugin) {
new OutputChest(itemGroups.basicMachines, SlimefunItems.OUTPUT_CHEST, RecipeType.ENHANCED_CRAFTING_TABLE,
new ItemStack[] {SlimefunItems.LEAD_INGOT, new ItemStack(Material.HOPPER), SlimefunItems.LEAD_INGOT, SlimefunItems.LEAD_INGOT, new ItemStack(Material.CHEST), SlimefunItems.LEAD_INGOT, null, SlimefunItems.LEAD_INGOT, null})
.register(plugin);
-
+
new EnhancedCraftingTable(itemGroups.basicMachines, SlimefunItems.ENHANCED_CRAFTING_TABLE).register(plugin);
new PortableDustbin(itemGroups.usefulItems, SlimefunItems.PORTABLE_DUSTBIN, RecipeType.ENHANCED_CRAFTING_TABLE,
@@ -299,14 +300,14 @@ public static void setup(@Nonnull Slimefun plugin) {
new GrindStone(itemGroups.basicMachines, SlimefunItems.GRIND_STONE).register(plugin);
new ArmorForge(itemGroups.basicMachines, SlimefunItems.ARMOR_FORGE).register(plugin);
-
+
OreCrusher oreCrusher = new OreCrusher(itemGroups.basicMachines, SlimefunItems.ORE_CRUSHER);
oreCrusher.register(plugin);
-
+
new Compressor(itemGroups.basicMachines, SlimefunItems.COMPRESSOR).register(plugin);
new SlimefunItem(itemGroups.magicalResources, SlimefunItems.MAGIC_LUMP_1, RecipeType.GRIND_STONE,
- new ItemStack[] {new ItemStack(Material.NETHER_WART), null, null, null, null, null, null, null, null},
+ new ItemStack[] {new ItemStack(Material.NETHER_WART), null, null, null, null, null, null, null, null},
new SlimefunItemStack(SlimefunItems.MAGIC_LUMP_1, 2))
.register(plugin);
@@ -378,7 +379,7 @@ public static void setup(@Nonnull Slimefun plugin) {
new LongFallBoots(itemGroups.magicalArmor, SlimefunItems.SLIME_BOOTS, RecipeType.ARMOR_FORGE,
new ItemStack[] {null, null, null, new ItemStack(Material.SLIME_BALL), null, new ItemStack(Material.SLIME_BALL), new ItemStack(Material.IRON_INGOT), null, new ItemStack(Material.IRON_INGOT)},
- new PotionEffect[] {new PotionEffect(PotionEffectType.JUMP, 300, 5)},
+ new PotionEffect[] {new PotionEffect(VersionedPotionEffectType.JUMP_BOOST, 300, 5)},
SoundEffect.SLIME_BOOTS_FALL_SOUND)
.register(plugin);
@@ -416,11 +417,11 @@ public static void setup(@Nonnull Slimefun plugin) {
new MakeshiftSmeltery(itemGroups.basicMachines, SlimefunItems.MAKESHIFT_SMELTERY).register(plugin);
new Smeltery(itemGroups.basicMachines, SlimefunItems.SMELTERY).register(plugin);
-
+
new IgnitionChamber(itemGroups.basicMachines, SlimefunItems.IGNITION_CHAMBER, RecipeType.ENHANCED_CRAFTING_TABLE,
new ItemStack[] {new ItemStack(Material.IRON_INGOT), new ItemStack(Material.FLINT_AND_STEEL), new ItemStack(Material.IRON_INGOT), new ItemStack(Material.IRON_INGOT), SlimefunItems.BASIC_CIRCUIT_BOARD, new ItemStack(Material.IRON_INGOT), null, new ItemStack(Material.OBSERVER), null})
.register(plugin);
-
+
new PressureChamber(itemGroups.basicMachines, SlimefunItems.PRESSURE_CHAMBER).register(plugin);
new UnplaceableBlock(itemGroups.technicalComponents, SlimefunItems.BATTERY, RecipeType.ENHANCED_CRAFTING_TABLE,
@@ -429,9 +430,9 @@ public static void setup(@Nonnull Slimefun plugin) {
registerArmorSet(itemGroups.magicalArmor, new ItemStack(Material.GLOWSTONE), new ItemStack[] {SlimefunItems.GLOWSTONE_HELMET, SlimefunItems.GLOWSTONE_CHESTPLATE, SlimefunItems.GLOWSTONE_LEGGINGS, SlimefunItems.GLOWSTONE_BOOTS}, "GLOWSTONE", false,
new PotionEffect[][] {
- new PotionEffect[] {new PotionEffect(PotionEffectType.NIGHT_VISION, 600, 0)},
- new PotionEffect[] {new PotionEffect(PotionEffectType.NIGHT_VISION, 600, 0)},
- new PotionEffect[] {new PotionEffect(PotionEffectType.NIGHT_VISION, 600, 0)},
+ new PotionEffect[] {new PotionEffect(PotionEffectType.NIGHT_VISION, 600, 0)},
+ new PotionEffect[] {new PotionEffect(PotionEffectType.NIGHT_VISION, 600, 0)},
+ new PotionEffect[] {new PotionEffect(PotionEffectType.NIGHT_VISION, 600, 0)},
new PotionEffect[] {new PotionEffect(PotionEffectType.NIGHT_VISION, 600, 0)}
}, plugin);
@@ -551,12 +552,12 @@ public static void setup(@Nonnull Slimefun plugin) {
.register(plugin);
new SlimefunItem(itemGroups.resources, SlimefunItems.IRON_DUST, RecipeType.ORE_CRUSHER,
- new ItemStack[] {new ItemStack(Material.IRON_ORE), null, null, null, null, null, null, null, null},
+ new ItemStack[] {new ItemStack(Material.IRON_ORE), null, null, null, null, null, null, null, null},
new SlimefunItemStack(SlimefunItems.IRON_DUST, oreCrusher.isOreDoublingEnabled() ? 2 : 1))
.register(plugin);
new SlimefunItem(itemGroups.resources, SlimefunItems.GOLD_DUST, RecipeType.ORE_CRUSHER,
- new ItemStack[] {new ItemStack(Material.GOLD_ORE), null, null, null, null, null, null, null, null},
+ new ItemStack[] {new ItemStack(Material.GOLD_ORE), null, null, null, null, null, null, null, null},
new SlimefunItemStack(SlimefunItems.GOLD_DUST, oreCrusher.isOreDoublingEnabled() ? 2 : 1))
.register(plugin);
@@ -571,7 +572,7 @@ public static void setup(@Nonnull Slimefun plugin) {
new SlimefunItem(itemGroups.resources, SlimefunItems.SILVER_DUST, RecipeType.ORE_WASHER,
new ItemStack[] {SlimefunItems.SIFTED_ORE, null, null, null, null, null, null, null, null})
.register(plugin);
-
+
new SlimefunItem(itemGroups.resources, SlimefunItems.LEAD_DUST, RecipeType.ORE_WASHER,
new ItemStack[] {SlimefunItems.SIFTED_ORE, null, null, null, null, null, null, null, null})
.register(plugin);
@@ -693,12 +694,12 @@ public static void setup(@Nonnull Slimefun plugin) {
.register(plugin);
new HologramProjector(itemGroups.technicalGadgets, SlimefunItems.HOLOGRAM_PROJECTOR, RecipeType.ENHANCED_CRAFTING_TABLE,
- new ItemStack[] {null, SlimefunItems.POWER_CRYSTAL, null, SlimefunItems.ALUMINUM_BRASS_INGOT, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.ALUMINUM_BRASS_INGOT, null, SlimefunItems.ALUMINUM_BRASS_INGOT, null},
+ new ItemStack[] {null, SlimefunItems.POWER_CRYSTAL, null, SlimefunItems.ALUMINUM_BRASS_INGOT, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.ALUMINUM_BRASS_INGOT, null, SlimefunItems.ALUMINUM_BRASS_INGOT, null},
new SlimefunItemStack(SlimefunItems.HOLOGRAM_PROJECTOR, 3))
.register(plugin);
new UnplaceableBlock(itemGroups.misc, SlimefunItems.CHAIN, RecipeType.ENHANCED_CRAFTING_TABLE,
- new ItemStack[] {null, null, SlimefunItems.STEEL_INGOT, null, SlimefunItems.STEEL_INGOT, null, SlimefunItems.STEEL_INGOT, null, null},
+ new ItemStack[] {null, null, SlimefunItems.STEEL_INGOT, null, SlimefunItems.STEEL_INGOT, null, SlimefunItems.STEEL_INGOT, null, null},
new SlimefunItemStack(SlimefunItems.CHAIN, 8))
.register(plugin);
@@ -723,11 +724,11 @@ public static void setup(@Nonnull Slimefun plugin) {
new WaterStaff(itemGroups.magicalGadgets, SlimefunItems.STAFF_WATER, RecipeType.MAGIC_WORKBENCH,
new ItemStack[] {null, new ItemStack(Material.LILY_PAD), SlimefunItems.MAGIC_LUMP_2, null, SlimefunItems.STAFF_ELEMENTAL, new ItemStack(Material.LILY_PAD), SlimefunItems.STAFF_ELEMENTAL, null, null})
.register(plugin);
-
+
new EnchantedItem(itemGroups.magicalGadgets, SlimefunItems.STAFF_FIRE, RecipeType.MAGIC_WORKBENCH,
new ItemStack[] {null, null, SlimefunItems.LAVA_CRYSTAL, null, SlimefunItems.STAFF_ELEMENTAL, null, SlimefunItems.STAFF_ELEMENTAL, null, null})
- .register(plugin);
-
+ .register(plugin);
+
String[] multiToolItems = new String[] {"PORTABLE_CRAFTER", "MAGIC_EYE_OF_ENDER", "STAFF_ELEMENTAL_WIND", "GRAPPLING_HOOK"};
new MultiTool(itemGroups.technicalGadgets, SlimefunItems.DURALUMIN_MULTI_TOOL, RecipeType.ENHANCED_CRAFTING_TABLE,
@@ -832,14 +833,18 @@ public static void setup(@Nonnull Slimefun plugin) {
new UnplaceableBlock(itemGroups.magicalResources, SlimefunItems.LAVA_CRYSTAL, RecipeType.ENHANCED_CRAFTING_TABLE,
new ItemStack[] {SlimefunItems.MAGIC_LUMP_1, new ItemStack(Material.BLAZE_POWDER), SlimefunItems.MAGIC_LUMP_1, new ItemStack(Material.BLAZE_POWDER), SlimefunItems.FIRE_RUNE, new ItemStack(Material.BLAZE_POWDER), SlimefunItems.MAGIC_LUMP_1, new ItemStack(Material.BLAZE_POWDER), SlimefunItems.MAGIC_LUMP_1})
.register(plugin);
-
+
new StormStaff(itemGroups.magicalGadgets, SlimefunItems.STAFF_STORM, RecipeType.ANCIENT_ALTAR,
new ItemStack[] {SlimefunItems.LIGHTNING_RUNE, SlimefunItems.ENDER_LUMP_3, SlimefunItems.LIGHTNING_RUNE, SlimefunItems.STAFF_WATER, SlimefunItems.MAGIC_SUGAR, SlimefunItems.STAFF_WIND, SlimefunItems.LIGHTNING_RUNE, SlimefunItems.ENDER_LUMP_3, SlimefunItems.LIGHTNING_RUNE})
.register(plugin);
ItemStack weaknessPotion = new ItemStack(Material.POTION);
PotionMeta meta = (PotionMeta) weaknessPotion.getItemMeta();
- meta.setBasePotionData(new PotionData(PotionType.WEAKNESS, false, false));
+ if (Slimefun.getMinecraftVersion().isBefore(20, 2)) {
+ meta.setBasePotionData(new PotionData(PotionType.WEAKNESS, false, false));
+ } else {
+ meta.setBasePotionType(PotionType.WEAKNESS);
+ }
weaknessPotion.setItemMeta(meta);
new MagicalZombiePills(itemGroups.magicalGadgets, SlimefunItems.MAGICAL_ZOMBIE_PILLS, RecipeType.MAGIC_WORKBENCH,
@@ -907,7 +912,7 @@ public static void setup(@Nonnull Slimefun plugin) {
new Talisman(SlimefunItems.TALISMAN_WARRIOR,
new ItemStack[] {SlimefunItems.MAGIC_LUMP_3, null, SlimefunItems.MAGIC_LUMP_3, SlimefunItems.REINFORCED_ALLOY_INGOT, SlimefunItems.COMMON_TALISMAN, SlimefunItems.REINFORCED_ALLOY_INGOT, SlimefunItems.MAGIC_LUMP_3, null, SlimefunItems.MAGIC_LUMP_3},
- true, true, "warrior", new PotionEffect(PotionEffectType.INCREASE_DAMAGE, 3600, 2))
+ true, true, "warrior", new PotionEffect(VersionedPotionEffectType.STRENGTH, 3600, 2))
.register(plugin);
new Talisman(SlimefunItems.TALISMAN_KNIGHT,
@@ -917,7 +922,7 @@ public static void setup(@Nonnull Slimefun plugin) {
new Talisman(SlimefunItems.TALISMAN_CAVEMAN,
new ItemStack[] { SlimefunItems.MAGIC_LUMP_3, null, SlimefunItems.MAGIC_LUMP_3, new ItemStack(Material.GOLDEN_PICKAXE), SlimefunItems.TALISMAN_MINER, SlimefunItems.EARTH_RUNE, SlimefunItems.MAGIC_LUMP_3, null, SlimefunItems.MAGIC_LUMP_3},
- false, false, "caveman", 50, new PotionEffect(PotionEffectType.FAST_DIGGING, 800, 2))
+ false, false, "caveman", 50, new PotionEffect(VersionedPotionEffectType.HASTE, 800, 2))
.register(plugin);
new Talisman(SlimefunItems.TALISMAN_WISE,
@@ -946,7 +951,7 @@ public static void setup(@Nonnull Slimefun plugin) {
new ItemStack[] {SlimefunItems.ENDER_LUMP_3, null, SlimefunItems.ENDER_LUMP_3, SlimefunItems.MAGIC_EYE_OF_ENDER, SlimefunItems.TALISMAN_MAGICIAN, SlimefunItems.MAGIC_EYE_OF_ENDER, SlimefunItems.ENDER_LUMP_3, null, SlimefunItems.ENDER_LUMP_3},
false, false, "wizard", 60)
.register(plugin);
-
+
new LumberAxe(itemGroups.tools, SlimefunItems.LUMBER_AXE, RecipeType.MAGIC_WORKBENCH,
new ItemStack[] {SlimefunItems.SYNTHETIC_DIAMOND, SlimefunItems.SYNTHETIC_DIAMOND, null, SlimefunItems.SYNTHETIC_EMERALD, SlimefunItems.GILDED_IRON, null, null, SlimefunItems.GILDED_IRON, null})
.register(plugin);
@@ -956,7 +961,7 @@ public static void setup(@Nonnull Slimefun plugin) {
.register(plugin);
new HeavyCream(itemGroups.misc, SlimefunItems.HEAVY_CREAM, RecipeType.ENHANCED_CRAFTING_TABLE,
- new ItemStack[] {new ItemStack(Material.MILK_BUCKET), null, null, null, null, null, null, null, null},
+ new ItemStack[] {new ItemStack(Material.MILK_BUCKET), null, null, null, null, null, null, null, null},
new SlimefunItemStack(SlimefunItems.HEAVY_CREAM, 2))
.register(plugin);
@@ -971,7 +976,7 @@ public static void setup(@Nonnull Slimefun plugin) {
registerArmorSet(itemGroups.armor, SlimefunItems.GILDED_IRON, new ItemStack[] {
SlimefunItems.GILDED_IRON_HELMET, SlimefunItems.GILDED_IRON_CHESTPLATE, SlimefunItems.GILDED_IRON_LEGGINGS, SlimefunItems.GILDED_IRON_BOOTS
}, "GILDED_IRON", false, new PotionEffect[0][0], plugin);
-
+
new SlimefunItem(itemGroups.technicalComponents, SlimefunItems.REINFORCED_CLOTH, RecipeType.ENHANCED_CRAFTING_TABLE,
new ItemStack[] {null, SlimefunItems.CLOTH, null, SlimefunItems.CLOTH, SlimefunItems.LEAD_INGOT, SlimefunItems.CLOTH, null, SlimefunItems.CLOTH, null}, new SlimefunItemStack(SlimefunItems.REINFORCED_CLOTH, 2))
.register(plugin);
@@ -1027,7 +1032,7 @@ public static void setup(@Nonnull Slimefun plugin) {
}, "GOLD_12K", false, new PotionEffect[0][0], plugin);
new SlimefunItem(itemGroups.misc, SlimefunItems.CLOTH, RecipeType.ENHANCED_CRAFTING_TABLE,
- new ItemStack[] {new ItemStack(Material.WHITE_WOOL), null, null, null, null, null, null, null, null},
+ new ItemStack[] {new ItemStack(Material.WHITE_WOOL), null, null, null, null, null, null, null, null},
new SlimefunItemStack(SlimefunItems.CLOTH, 8))
.register(plugin);
@@ -1037,17 +1042,17 @@ public static void setup(@Nonnull Slimefun plugin) {
.register(plugin);
new Bandage(itemGroups.usefulItems, SlimefunItems.BANDAGE, RecipeType.ENHANCED_CRAFTING_TABLE,
- new ItemStack[] {SlimefunItems.RAG, new ItemStack(Material.STRING), SlimefunItems.RAG, null, null, null, null, null, null},
+ new ItemStack[] {SlimefunItems.RAG, new ItemStack(Material.STRING), SlimefunItems.RAG, null, null, null, null, null, null},
new SlimefunItemStack(SlimefunItems.BANDAGE, 4), 1)
.register(plugin);
new Splint(itemGroups.usefulItems, SlimefunItems.SPLINT, RecipeType.ENHANCED_CRAFTING_TABLE,
- new ItemStack[] {null, new ItemStack(Material.IRON_INGOT), null, new ItemStack(Material.STICK), new ItemStack(Material.STICK), new ItemStack(Material.STICK), null, new ItemStack(Material.IRON_INGOT), null},
+ new ItemStack[] {null, new ItemStack(Material.IRON_INGOT), null, new ItemStack(Material.STICK), new ItemStack(Material.STICK), new ItemStack(Material.STICK), null, new ItemStack(Material.IRON_INGOT), null},
new SlimefunItemStack(SlimefunItems.SPLINT, 4))
.register(plugin);
new UnplaceableBlock(itemGroups.misc, SlimefunItems.TIN_CAN, RecipeType.ENHANCED_CRAFTING_TABLE,
- new ItemStack[] {SlimefunItems.TIN_INGOT, SlimefunItems.TIN_INGOT, SlimefunItems.TIN_INGOT, SlimefunItems.TIN_INGOT, null, SlimefunItems.TIN_INGOT, SlimefunItems.TIN_INGOT, SlimefunItems.TIN_INGOT, SlimefunItems.TIN_INGOT},
+ new ItemStack[] {SlimefunItems.TIN_INGOT, SlimefunItems.TIN_INGOT, SlimefunItems.TIN_INGOT, SlimefunItems.TIN_INGOT, null, SlimefunItems.TIN_INGOT, SlimefunItems.TIN_INGOT, SlimefunItems.TIN_INGOT, SlimefunItems.TIN_INGOT},
new SlimefunItemStack(SlimefunItems.TIN_CAN, 8))
.register(plugin);
@@ -1067,7 +1072,7 @@ public static void setup(@Nonnull Slimefun plugin) {
new PickaxeOfContainment(itemGroups.tools, SlimefunItems.PICKAXE_OF_CONTAINMENT, RecipeType.MAGIC_WORKBENCH,
new ItemStack[] {SlimefunItems.FERROSILICON, SlimefunItems.FERROSILICON, SlimefunItems.FERROSILICON, null, SlimefunItems.GILDED_IRON, null, null, SlimefunItems.GILDED_IRON, null})
.register(plugin);
-
+
new TableSaw(itemGroups.basicMachines, SlimefunItems.TABLE_SAW).register(plugin);
new SlimefunArmorPiece(itemGroups.magicalArmor, SlimefunItems.SLIME_HELMET_STEEL, RecipeType.ARMOR_FORGE,
@@ -1085,7 +1090,7 @@ public static void setup(@Nonnull Slimefun plugin) {
new LongFallBoots(itemGroups.magicalArmor, SlimefunItems.SLIME_BOOTS_STEEL, RecipeType.ARMOR_FORGE,
new ItemStack[] {null, null, null, new ItemStack(Material.SLIME_BALL), null, new ItemStack(Material.SLIME_BALL), new ItemStack(Material.SLIME_BALL), SlimefunItems.STEEL_PLATE, new ItemStack(Material.SLIME_BALL)},
- new PotionEffect[] {new PotionEffect(PotionEffectType.JUMP, 300, 5)},
+ new PotionEffect[] {new PotionEffect(VersionedPotionEffectType.JUMP_BOOST, 300, 5)},
SoundEffect.SLIME_BOOTS_FALL_SOUND)
.register(plugin);
@@ -1104,7 +1109,7 @@ public static void setup(@Nonnull Slimefun plugin) {
new FarmerShoes(itemGroups.magicalArmor, SlimefunItems.FARMER_SHOES, RecipeType.ARMOR_FORGE,
new ItemStack[] {null, null, null, new ItemStack(Material.HAY_BLOCK), null, new ItemStack(Material.HAY_BLOCK), new ItemStack(Material.HAY_BLOCK), null, new ItemStack(Material.HAY_BLOCK)})
.register(plugin);
-
+
new ExplosivePickaxe(itemGroups.tools, SlimefunItems.EXPLOSIVE_PICKAXE, RecipeType.MAGIC_WORKBENCH,
new ItemStack[] {new ItemStack(Material.TNT), SlimefunItems.SYNTHETIC_DIAMOND, new ItemStack(Material.TNT), null, SlimefunItems.FERROSILICON, null, null, SlimefunItems.FERROSILICON, null})
.register(plugin);
@@ -1114,7 +1119,7 @@ public static void setup(@Nonnull Slimefun plugin) {
.register(plugin);
new AutomatedPanningMachine(itemGroups.basicMachines, SlimefunItems.AUTOMATED_PANNING_MACHINE).register(plugin);
-
+
new IndustrialMiner(itemGroups.basicMachines, SlimefunItems.INDUSTRIAL_MINER, Material.IRON_BLOCK, false, 3).register(plugin);
new AdvancedIndustrialMiner(itemGroups.basicMachines, SlimefunItems.ADVANCED_INDUSTRIAL_MINER).register(plugin);
@@ -1232,7 +1237,7 @@ public static void setup(@Nonnull Slimefun plugin) {
new PickaxeOfVeinMining(itemGroups.tools, SlimefunItems.PICKAXE_OF_VEIN_MINING, RecipeType.MAGIC_WORKBENCH,
new ItemStack[] {new ItemStack(Material.EMERALD_ORE), SlimefunItems.SYNTHETIC_DIAMOND, new ItemStack(Material.EMERALD_ORE), null, SlimefunItems.GILDED_IRON, null, null, SlimefunItems.GILDED_IRON, null})
.register(plugin);
-
+
new ClimbingPick(itemGroups.tools, SlimefunItems.CLIMBING_PICK, RecipeType.ENHANCED_CRAFTING_TABLE,
new ItemStack[] {SlimefunItems.STEEL_INGOT, SlimefunItems.HARDENED_METAL_INGOT, SlimefunItems.STEEL_INGOT, null, new ItemStack(Material.STICK), null, null, new ItemStack(Material.STICK), null})
.register(plugin);
@@ -1240,7 +1245,7 @@ public static void setup(@Nonnull Slimefun plugin) {
new SoulboundItem(itemGroups.weapons, SlimefunItems.SOULBOUND_SWORD, RecipeType.MAGIC_WORKBENCH,
new ItemStack[] {null, SlimefunItems.ESSENCE_OF_AFTERLIFE, null, null, new ItemStack(Material.DIAMOND_SWORD), null, null, SlimefunItems.ESSENCE_OF_AFTERLIFE, null})
.register(plugin);
-
+
new SoulboundItem(itemGroups.weapons, SlimefunItems.SOULBOUND_TRIDENT, RecipeType.MAGIC_WORKBENCH,
new ItemStack[] {null, SlimefunItems.ESSENCE_OF_AFTERLIFE, null, null, new ItemStack(Material.TRIDENT), null, null, SlimefunItems.ESSENCE_OF_AFTERLIFE, null})
.register(plugin);
@@ -1384,10 +1389,10 @@ public static void setup(@Nonnull Slimefun plugin) {
.register(plugin);
new UnplaceableBlock(itemGroups.technicalComponents, SlimefunItems.COPPER_WIRE, RecipeType.ENHANCED_CRAFTING_TABLE,
- new ItemStack[] {null, null, null, SlimefunItems.COPPER_INGOT, SlimefunItems.COPPER_INGOT, SlimefunItems.COPPER_INGOT, null, null, null},
+ new ItemStack[] {null, null, null, SlimefunItems.COPPER_INGOT, SlimefunItems.COPPER_INGOT, SlimefunItems.COPPER_INGOT, null, null, null},
new SlimefunItemStack(SlimefunItems.COPPER_WIRE, 8))
.register(plugin);
-
+
new BlockPlacer(itemGroups.basicMachines, SlimefunItems.BLOCK_PLACER, RecipeType.ENHANCED_CRAFTING_TABLE,
new ItemStack[] {SlimefunItems.GOLD_4K, new ItemStack(Material.PISTON), SlimefunItems.GOLD_4K, new ItemStack(Material.IRON_INGOT), SlimefunItems.ELECTRIC_MOTOR, new ItemStack(Material.IRON_INGOT), SlimefunItems.GOLD_4K, new ItemStack(Material.PISTON), SlimefunItems.GOLD_4K})
.register(plugin);
@@ -1409,7 +1414,7 @@ public static void setup(@Nonnull Slimefun plugin) {
.register(plugin);
new KnowledgeFlask(itemGroups.magicalGadgets, SlimefunItems.FLASK_OF_KNOWLEDGE, RecipeType.MAGIC_WORKBENCH,
- new ItemStack[] {null, null, null, SlimefunItems.MAGIC_LUMP_2, new ItemStack(Material.GLASS_PANE), SlimefunItems.MAGIC_LUMP_2, null, SlimefunItems.MAGIC_LUMP_2, null},
+ new ItemStack[] {null, null, null, SlimefunItems.MAGIC_LUMP_2, new ItemStack(Material.GLASS_PANE), SlimefunItems.MAGIC_LUMP_2, null, SlimefunItems.MAGIC_LUMP_2, null},
new SlimefunItemStack(SlimefunItems.FLASK_OF_KNOWLEDGE, 8))
.register(plugin);
@@ -1422,37 +1427,37 @@ public static void setup(@Nonnull Slimefun plugin) {
.register(plugin);
new Juice(itemGroups.christmas, SlimefunItems.CHRISTMAS_MILK, RecipeType.ENHANCED_CRAFTING_TABLE,
- new ItemStack[] {new ItemStack(Material.MILK_BUCKET), new ItemStack(Material.GLASS_BOTTLE), null, null, null, null, null, null, null},
+ new ItemStack[] {new ItemStack(Material.MILK_BUCKET), new ItemStack(Material.GLASS_BOTTLE), null, null, null, null, null, null, null},
new SlimefunItemStack(SlimefunItems.CHRISTMAS_MILK, 4))
.register(plugin);
new Juice(itemGroups.christmas, SlimefunItems.CHRISTMAS_CHOCOLATE_MILK, RecipeType.ENHANCED_CRAFTING_TABLE,
- new ItemStack[] {SlimefunItems.CHRISTMAS_MILK, new ItemStack(Material.COCOA_BEANS), null, null, null, null, null, null, null},
+ new ItemStack[] {SlimefunItems.CHRISTMAS_MILK, new ItemStack(Material.COCOA_BEANS), null, null, null, null, null, null, null},
new SlimefunItemStack(SlimefunItems.CHRISTMAS_CHOCOLATE_MILK, 2))
.register(plugin);
new Juice(itemGroups.christmas, SlimefunItems.CHRISTMAS_EGG_NOG, RecipeType.ENHANCED_CRAFTING_TABLE,
- new ItemStack[] {SlimefunItems.CHRISTMAS_MILK, new ItemStack(Material.EGG), null, null, null, null, null, null, null},
+ new ItemStack[] {SlimefunItems.CHRISTMAS_MILK, new ItemStack(Material.EGG), null, null, null, null, null, null, null},
new SlimefunItemStack(SlimefunItems.CHRISTMAS_EGG_NOG, 2))
.register(plugin);
new Juice(itemGroups.christmas, SlimefunItems.CHRISTMAS_APPLE_CIDER, RecipeType.ENHANCED_CRAFTING_TABLE,
- new ItemStack[] {SlimefunItems.APPLE_JUICE, new ItemStack(Material.SUGAR), null, null, null, null, null, null, null},
+ new ItemStack[] {SlimefunItems.APPLE_JUICE, new ItemStack(Material.SUGAR), null, null, null, null, null, null, null},
new SlimefunItemStack(SlimefunItems.CHRISTMAS_APPLE_CIDER, 2))
.register(plugin);
new SlimefunItem(itemGroups.christmas, SlimefunItems.CHRISTMAS_COOKIE, RecipeType.ENHANCED_CRAFTING_TABLE,
- new ItemStack[] {new ItemStack(Material.COOKIE), new ItemStack(Material.SUGAR), new ItemStack(Material.LIME_DYE), null, null, null, null, null, null},
+ new ItemStack[] {new ItemStack(Material.COOKIE), new ItemStack(Material.SUGAR), new ItemStack(Material.LIME_DYE), null, null, null, null, null, null},
new SlimefunItemStack(SlimefunItems.CHRISTMAS_COOKIE, 16))
.register(plugin);
new SlimefunItem(itemGroups.christmas, SlimefunItems.CHRISTMAS_FRUIT_CAKE, RecipeType.ENHANCED_CRAFTING_TABLE,
- new ItemStack[] {new ItemStack(Material.EGG), new ItemStack(Material.APPLE), new ItemStack(Material.MELON), new ItemStack(Material.SUGAR), null, null, null, null, null},
+ new ItemStack[] {new ItemStack(Material.EGG), new ItemStack(Material.APPLE), new ItemStack(Material.MELON), new ItemStack(Material.SUGAR), null, null, null, null, null},
new SlimefunItemStack(SlimefunItems.CHRISTMAS_FRUIT_CAKE, 4))
.register(plugin);
new SlimefunItem(itemGroups.christmas, SlimefunItems.CHRISTMAS_APPLE_PIE, RecipeType.ENHANCED_CRAFTING_TABLE,
- new ItemStack[] {new ItemStack(Material.SUGAR), new ItemStack(Material.APPLE), new ItemStack(Material.EGG), null, null, null, null, null, null},
+ new ItemStack[] {new ItemStack(Material.SUGAR), new ItemStack(Material.APPLE), new ItemStack(Material.EGG), null, null, null, null, null, null},
new SlimefunItemStack(SlimefunItems.CHRISTMAS_APPLE_PIE, 2))
.register(plugin);
@@ -1461,22 +1466,22 @@ public static void setup(@Nonnull Slimefun plugin) {
.register(plugin);
new SlimefunItem(itemGroups.christmas, SlimefunItems.CHRISTMAS_CAKE, RecipeType.ENHANCED_CRAFTING_TABLE,
- new ItemStack[] {new ItemStack(Material.EGG), new ItemStack(Material.SUGAR), SlimefunItems.WHEAT_FLOUR, new ItemStack(Material.MILK_BUCKET), null, null, null, null, null},
+ new ItemStack[] {new ItemStack(Material.EGG), new ItemStack(Material.SUGAR), SlimefunItems.WHEAT_FLOUR, new ItemStack(Material.MILK_BUCKET), null, null, null, null, null},
new SlimefunItemStack(SlimefunItems.CHRISTMAS_CAKE, 4))
.register(plugin);
new SlimefunItem(itemGroups.christmas, SlimefunItems.CHRISTMAS_CARAMEL, RecipeType.SMELTERY,
- new ItemStack[] {new ItemStack(Material.SUGAR), new ItemStack(Material.SUGAR), null, null, null, null, null, null, null},
+ new ItemStack[] {new ItemStack(Material.SUGAR), new ItemStack(Material.SUGAR), null, null, null, null, null, null, null},
new SlimefunItemStack(SlimefunItems.CHRISTMAS_CARAMEL, 4))
.register(plugin);
new SlimefunItem(itemGroups.christmas, SlimefunItems.CHRISTMAS_CARAMEL_APPLE, RecipeType.ENHANCED_CRAFTING_TABLE,
- new ItemStack[] {null, SlimefunItems.CHRISTMAS_CARAMEL, null, null, new ItemStack(Material.APPLE), null, null, new ItemStack(Material.STICK), null},
+ new ItemStack[] {null, SlimefunItems.CHRISTMAS_CARAMEL, null, null, new ItemStack(Material.APPLE), null, null, new ItemStack(Material.STICK), null},
new SlimefunItemStack(SlimefunItems.CHRISTMAS_CARAMEL_APPLE, 2))
.register(plugin);
new SlimefunItem(itemGroups.christmas, SlimefunItems.CHRISTMAS_CHOCOLATE_APPLE, RecipeType.ENHANCED_CRAFTING_TABLE,
- new ItemStack[] {null, new ItemStack(Material.COCOA_BEANS), null, null, new ItemStack(Material.APPLE), null, null, new ItemStack(Material.STICK), null},
+ new ItemStack[] {null, new ItemStack(Material.COCOA_BEANS), null, null, new ItemStack(Material.APPLE), null, null, new ItemStack(Material.STICK), null},
new SlimefunItemStack(SlimefunItems.CHRISTMAS_CHOCOLATE_APPLE, 2))
.register(plugin);
@@ -1497,17 +1502,17 @@ public static void setup(@Nonnull Slimefun plugin) {
).register(plugin);
new SlimefunItem(itemGroups.easter, SlimefunItems.EASTER_CARROT_PIE, RecipeType.ENHANCED_CRAFTING_TABLE,
- new ItemStack[] {new ItemStack(Material.SUGAR), new ItemStack(Material.CARROT), new ItemStack(Material.EGG), null, null, null, null, null, null},
+ new ItemStack[] {new ItemStack(Material.SUGAR), new ItemStack(Material.CARROT), new ItemStack(Material.EGG), null, null, null, null, null, null},
new SlimefunItemStack(SlimefunItems.EASTER_CARROT_PIE, 2))
.register(plugin);
new SlimefunItem(itemGroups.easter, SlimefunItems.EASTER_APPLE_PIE, RecipeType.ENHANCED_CRAFTING_TABLE,
- new ItemStack[] {new ItemStack(Material.SUGAR), new ItemStack(Material.APPLE), new ItemStack(Material.EGG), null, null, null, null, null, null},
+ new ItemStack[] {new ItemStack(Material.SUGAR), new ItemStack(Material.APPLE), new ItemStack(Material.EGG), null, null, null, null, null, null},
new SlimefunItemStack(SlimefunItems.EASTER_APPLE_PIE, 2))
.register(plugin);
new EasterEgg(itemGroups.easter, SlimefunItems.EASTER_EGG, RecipeType.ENHANCED_CRAFTING_TABLE,
- new ItemStack[] {null, null, null, new ItemStack(Material.LIME_DYE), new ItemStack(Material.EGG), new ItemStack(Material.PURPLE_DYE), null, null, null},
+ new ItemStack[] {null, null, null, new ItemStack(Material.LIME_DYE), new ItemStack(Material.EGG), new ItemStack(Material.PURPLE_DYE), null, null, null},
new SlimefunItemStack(SlimefunItems.EASTER_EGG, 2),
// Gifts:
new SlimefunItemStack(SlimefunItems.EASTER_CARROT_PIE, 4),
@@ -1543,7 +1548,7 @@ public static void setup(@Nonnull Slimefun plugin) {
.register(plugin);
new AncientPedestal(itemGroups.magicalGadgets, SlimefunItems.ANCIENT_PEDESTAL, RecipeType.MAGIC_WORKBENCH,
- new ItemStack[] {new ItemStack(Material.OBSIDIAN), SlimefunItems.GOLD_8K, new ItemStack(Material.OBSIDIAN), null, new ItemStack(Material.STONE), null, new ItemStack(Material.OBSIDIAN), SlimefunItems.GOLD_8K, new ItemStack(Material.OBSIDIAN)},
+ new ItemStack[] {new ItemStack(Material.OBSIDIAN), SlimefunItems.GOLD_8K, new ItemStack(Material.OBSIDIAN), null, new ItemStack(Material.STONE), null, new ItemStack(Material.OBSIDIAN), SlimefunItems.GOLD_8K, new ItemStack(Material.OBSIDIAN)},
new SlimefunItemStack(SlimefunItems.ANCIENT_PEDESTAL, 4))
.register(plugin);
@@ -1561,7 +1566,7 @@ public static void setup(@Nonnull Slimefun plugin) {
.register(plugin);
new SlimefunItem(itemGroups.misc, SlimefunItems.DUCT_TAPE, RecipeType.ENHANCED_CRAFTING_TABLE,
- new ItemStack[] {SlimefunItems.ALUMINUM_DUST, SlimefunItems.ALUMINUM_DUST, SlimefunItems.ALUMINUM_DUST, new ItemStack(Material.SLIME_BALL), new ItemStack(Material.WHITE_WOOL), new ItemStack(Material.SLIME_BALL), new ItemStack(Material.PAPER), new ItemStack(Material.PAPER), new ItemStack(Material.PAPER)},
+ new ItemStack[] {SlimefunItems.ALUMINUM_DUST, SlimefunItems.ALUMINUM_DUST, SlimefunItems.ALUMINUM_DUST, new ItemStack(Material.SLIME_BALL), new ItemStack(Material.WHITE_WOOL), new ItemStack(Material.SLIME_BALL), new ItemStack(Material.PAPER), new ItemStack(Material.PAPER), new ItemStack(Material.PAPER)},
new SlimefunItemStack(SlimefunItems.DUCT_TAPE, 2))
.register(plugin);
@@ -1604,7 +1609,7 @@ public static void setup(@Nonnull Slimefun plugin) {
new SolarGenerator(itemGroups.electricity, 128, 64, SlimefunItems.SOLAR_GENERATOR_4, RecipeType.ENHANCED_CRAFTING_TABLE,
new ItemStack[] {SlimefunItems.SOLAR_GENERATOR_3, SlimefunItems.BLISTERING_INGOT_3, SlimefunItems.SOLAR_GENERATOR_3, SlimefunItems.BLISTERING_INGOT_3, SlimefunItems.ELECTRO_MAGNET, SlimefunItems.BLISTERING_INGOT_3, SlimefunItems.SOLAR_GENERATOR_3, SlimefunItems.BLISTERING_INGOT_3, SlimefunItems.SOLAR_GENERATOR_3})
.register(plugin);
-
+
new ChargingBench(itemGroups.electricity, SlimefunItems.CHARGING_BENCH, RecipeType.ENHANCED_CRAFTING_TABLE,
new ItemStack[] {null, SlimefunItems.ELECTRO_MAGNET, null, SlimefunItems.BATTERY, new ItemStack(Material.CRAFTING_TABLE), SlimefunItems.BATTERY, null, SlimefunItems.SMALL_CAPACITOR, null})
.setCapacity(128)
@@ -1804,11 +1809,11 @@ public static void setup(@Nonnull Slimefun plugin) {
.setEnergyConsumption(20)
.setProcessingSpeed(3)
.register(plugin);
-
+
new SlimefunItem(itemGroups.resources, SlimefunItems.MAGNESIUM_SALT, RecipeType.HEATED_PRESSURE_CHAMBER,
new ItemStack[] {SlimefunItems.MAGNESIUM_DUST, SlimefunItems.SALT, null, null, null, null, null, null, null})
.register(plugin);
-
+
new MagnesiumGenerator(itemGroups.electricity, SlimefunItems.MAGNESIUM_GENERATOR, RecipeType.ENHANCED_CRAFTING_TABLE,
new ItemStack[] {null, SlimefunItems.ELECTRIC_MOTOR, null, SlimefunItems.COMPRESSED_CARBON, new ItemStack(Material.WATER_BUCKET), SlimefunItems.COMPRESSED_CARBON, SlimefunItems.DURALUMIN_INGOT, SlimefunItems.DURALUMIN_INGOT, SlimefunItems.DURALUMIN_INGOT})
.setCapacity(128)
@@ -1879,7 +1884,7 @@ public static void setup(@Nonnull Slimefun plugin) {
new GPSTransmitter(itemGroups.gps, 1, SlimefunItems.GPS_TRANSMITTER, RecipeType.ENHANCED_CRAFTING_TABLE,
new ItemStack[] {null, null, SlimefunItems.ELECTRO_MAGNET, SlimefunItems.STEEL_INGOT, SlimefunItems.ADVANCED_CIRCUIT_BOARD, SlimefunItems.STEEL_INGOT, SlimefunItems.STEEL_INGOT, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.STEEL_INGOT}) {
-
+
@Override
public int getMultiplier(int y) {
return y;
@@ -1894,7 +1899,7 @@ public int getEnergyConsumption() {
new GPSTransmitter(itemGroups.gps, 2, SlimefunItems.GPS_TRANSMITTER_2, RecipeType.ENHANCED_CRAFTING_TABLE,
new ItemStack[] {SlimefunItems.GPS_TRANSMITTER, SlimefunItems.BRONZE_INGOT, SlimefunItems.GPS_TRANSMITTER, SlimefunItems.BRONZE_INGOT, SlimefunItems.CARBON, SlimefunItems.BRONZE_INGOT, SlimefunItems.GPS_TRANSMITTER, SlimefunItems.BRONZE_INGOT, SlimefunItems.GPS_TRANSMITTER}) {
-
+
@Override
public int getMultiplier(int y) {
return y * 4 + 100;
@@ -1909,7 +1914,7 @@ public int getEnergyConsumption() {
new GPSTransmitter(itemGroups.gps, 3, SlimefunItems.GPS_TRANSMITTER_3, RecipeType.ENHANCED_CRAFTING_TABLE,
new ItemStack[] {SlimefunItems.GPS_TRANSMITTER_2, SlimefunItems.CORINTHIAN_BRONZE_INGOT, SlimefunItems.GPS_TRANSMITTER_2, SlimefunItems.CORINTHIAN_BRONZE_INGOT, SlimefunItems.CARBONADO, SlimefunItems.CORINTHIAN_BRONZE_INGOT, SlimefunItems.GPS_TRANSMITTER_2, SlimefunItems.CORINTHIAN_BRONZE_INGOT, SlimefunItems.GPS_TRANSMITTER_2}) {
-
+
@Override
public int getMultiplier(int y) {
return y * 16 + 500;
@@ -1924,7 +1929,7 @@ public int getEnergyConsumption() {
new GPSTransmitter(itemGroups.gps, 4, SlimefunItems.GPS_TRANSMITTER_4, RecipeType.ENHANCED_CRAFTING_TABLE,
new ItemStack[] {SlimefunItems.GPS_TRANSMITTER_3, SlimefunItems.BLISTERING_INGOT_3, SlimefunItems.GPS_TRANSMITTER_3, SlimefunItems.NICKEL_INGOT, SlimefunItems.CARBONADO, SlimefunItems.NICKEL_INGOT, SlimefunItems.GPS_TRANSMITTER_3, SlimefunItems.BLISTERING_INGOT_3, SlimefunItems.GPS_TRANSMITTER_3}) {
-
+
@Override
public int getMultiplier(int y) {
return y * 64 + 2100;
@@ -1934,7 +1939,7 @@ public int getMultiplier(int y) {
public int getEnergyConsumption() {
return 43;
}
-
+
}.register(plugin);
new GPSControlPanel(itemGroups.gps, SlimefunItems.GPS_CONTROL_PANEL, RecipeType.ENHANCED_CRAFTING_TABLE,
@@ -2014,32 +2019,32 @@ public int getEnergyConsumption() {
.register(plugin);
new ElementalRune(itemGroups.magicalResources, SlimefunItems.AIR_RUNE,
- new ItemStack[] {new ItemStack(Material.FEATHER), SlimefunItems.MAGIC_LUMP_1, new ItemStack(Material.FEATHER), new ItemStack(Material.GHAST_TEAR), SlimefunItems.BLANK_RUNE, new ItemStack(Material.GHAST_TEAR), new ItemStack(Material.FEATHER), SlimefunItems.MAGIC_LUMP_1, new ItemStack(Material.FEATHER)},
+ new ItemStack[] {new ItemStack(Material.FEATHER), SlimefunItems.MAGIC_LUMP_1, new ItemStack(Material.FEATHER), new ItemStack(Material.GHAST_TEAR), SlimefunItems.BLANK_RUNE, new ItemStack(Material.GHAST_TEAR), new ItemStack(Material.FEATHER), SlimefunItems.MAGIC_LUMP_1, new ItemStack(Material.FEATHER)},
new SlimefunItemStack(SlimefunItems.AIR_RUNE, 4))
.register(plugin);
new ElementalRune(itemGroups.magicalResources, SlimefunItems.EARTH_RUNE,
- new ItemStack[] {new ItemStack(Material.DIRT), SlimefunItems.MAGIC_LUMP_1, new ItemStack(Material.STONE), new ItemStack(Material.OBSIDIAN), SlimefunItems.BLANK_RUNE, new ItemStack(Material.OBSIDIAN), new ItemStack(Material.STONE), SlimefunItems.MAGIC_LUMP_1, new ItemStack(Material.DIRT)},
+ new ItemStack[] {new ItemStack(Material.DIRT), SlimefunItems.MAGIC_LUMP_1, new ItemStack(Material.STONE), new ItemStack(Material.OBSIDIAN), SlimefunItems.BLANK_RUNE, new ItemStack(Material.OBSIDIAN), new ItemStack(Material.STONE), SlimefunItems.MAGIC_LUMP_1, new ItemStack(Material.DIRT)},
new SlimefunItemStack(SlimefunItems.EARTH_RUNE, 4))
.register(plugin);
new ElementalRune(itemGroups.magicalResources, SlimefunItems.FIRE_RUNE,
- new ItemStack[] {new ItemStack(Material.FIRE_CHARGE), SlimefunItems.MAGIC_LUMP_2, new ItemStack(Material.FIRE_CHARGE), new ItemStack(Material.BLAZE_POWDER), SlimefunItems.EARTH_RUNE, new ItemStack(Material.FLINT_AND_STEEL), new ItemStack(Material.FIRE_CHARGE), SlimefunItems.MAGIC_LUMP_2, new ItemStack(Material.FIRE_CHARGE)},
+ new ItemStack[] {new ItemStack(Material.FIRE_CHARGE), SlimefunItems.MAGIC_LUMP_2, new ItemStack(Material.FIRE_CHARGE), new ItemStack(Material.BLAZE_POWDER), SlimefunItems.EARTH_RUNE, new ItemStack(Material.FLINT_AND_STEEL), new ItemStack(Material.FIRE_CHARGE), SlimefunItems.MAGIC_LUMP_2, new ItemStack(Material.FIRE_CHARGE)},
new SlimefunItemStack(SlimefunItems.FIRE_RUNE, 4))
.register(plugin);
new ElementalRune(itemGroups.magicalResources, SlimefunItems.WATER_RUNE,
- new ItemStack[] {new ItemStack(Material.SALMON), SlimefunItems.MAGIC_LUMP_2, new ItemStack(Material.WATER_BUCKET), new ItemStack(Material.SAND), SlimefunItems.BLANK_RUNE, new ItemStack(Material.SAND), new ItemStack(Material.WATER_BUCKET), SlimefunItems.MAGIC_LUMP_2, new ItemStack(Material.COD)},
+ new ItemStack[] {new ItemStack(Material.SALMON), SlimefunItems.MAGIC_LUMP_2, new ItemStack(Material.WATER_BUCKET), new ItemStack(Material.SAND), SlimefunItems.BLANK_RUNE, new ItemStack(Material.SAND), new ItemStack(Material.WATER_BUCKET), SlimefunItems.MAGIC_LUMP_2, new ItemStack(Material.COD)},
new SlimefunItemStack(SlimefunItems.WATER_RUNE, 4))
.register(plugin);
new ElementalRune(itemGroups.magicalResources, SlimefunItems.ENDER_RUNE,
- new ItemStack[] {new ItemStack(Material.ENDER_PEARL), SlimefunItems.ENDER_LUMP_3, new ItemStack(Material.ENDER_PEARL), new ItemStack(Material.ENDER_EYE), SlimefunItems.BLANK_RUNE, new ItemStack(Material.ENDER_EYE), new ItemStack(Material.ENDER_PEARL), SlimefunItems.ENDER_LUMP_3, new ItemStack(Material.ENDER_PEARL)},
+ new ItemStack[] {new ItemStack(Material.ENDER_PEARL), SlimefunItems.ENDER_LUMP_3, new ItemStack(Material.ENDER_PEARL), new ItemStack(Material.ENDER_EYE), SlimefunItems.BLANK_RUNE, new ItemStack(Material.ENDER_EYE), new ItemStack(Material.ENDER_PEARL), SlimefunItems.ENDER_LUMP_3, new ItemStack(Material.ENDER_PEARL)},
new SlimefunItemStack(SlimefunItems.ENDER_RUNE, 6))
.register(plugin);
new ElementalRune(itemGroups.magicalResources, SlimefunItems.LIGHTNING_RUNE,
- new ItemStack[] {new ItemStack(Material.IRON_INGOT), SlimefunItems.MAGIC_LUMP_3, new ItemStack(Material.IRON_INGOT), SlimefunItems.AIR_RUNE, new ItemStack(Material.PHANTOM_MEMBRANE), SlimefunItems.WATER_RUNE, new ItemStack(Material.IRON_INGOT), SlimefunItems.MAGIC_LUMP_3, new ItemStack(Material.IRON_INGOT)},
+ new ItemStack[] {new ItemStack(Material.IRON_INGOT), SlimefunItems.MAGIC_LUMP_3, new ItemStack(Material.IRON_INGOT), SlimefunItems.AIR_RUNE, new ItemStack(Material.PHANTOM_MEMBRANE), SlimefunItems.WATER_RUNE, new ItemStack(Material.IRON_INGOT), SlimefunItems.MAGIC_LUMP_3, new ItemStack(Material.IRON_INGOT)},
new SlimefunItemStack(SlimefunItems.LIGHTNING_RUNE, 4))
.register(plugin);
@@ -2056,7 +2061,7 @@ public int getEnergyConsumption() {
.register(plugin);
new InfernalBonemeal(itemGroups.magicalGadgets, SlimefunItems.INFERNAL_BONEMEAL, RecipeType.ANCIENT_ALTAR,
- new ItemStack[] {new ItemStack(Material.NETHER_WART), SlimefunItems.EARTH_RUNE, new ItemStack(Material.NETHER_WART), SlimefunItems.MAGIC_LUMP_2, new ItemStack(Material.BONE_MEAL), SlimefunItems.MAGIC_LUMP_2, new ItemStack(Material.NETHER_WART), new ItemStack(Material.BLAZE_POWDER), new ItemStack(Material.NETHER_WART)},
+ new ItemStack[] {new ItemStack(Material.NETHER_WART), SlimefunItems.EARTH_RUNE, new ItemStack(Material.NETHER_WART), SlimefunItems.MAGIC_LUMP_2, new ItemStack(Material.BONE_MEAL), SlimefunItems.MAGIC_LUMP_2, new ItemStack(Material.NETHER_WART), new ItemStack(Material.BLAZE_POWDER), new ItemStack(Material.NETHER_WART)},
new SlimefunItemStack(SlimefunItems.INFERNAL_BONEMEAL, 8))
.register(plugin);
@@ -2085,133 +2090,133 @@ public int getEnergyConsumption() {
.register(plugin);
new RainbowBlock(itemGroups.magicalGadgets, SlimefunItems.RAINBOW_WOOL, RecipeType.ANCIENT_ALTAR,
- new ItemStack[] {new ItemStack(Material.WHITE_WOOL), new ItemStack(Material.WHITE_WOOL), new ItemStack(Material.WHITE_WOOL), new ItemStack(Material.WHITE_WOOL), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_WOOL), new ItemStack(Material.WHITE_WOOL), new ItemStack(Material.WHITE_WOOL), new ItemStack(Material.WHITE_WOOL)},
+ new ItemStack[] {new ItemStack(Material.WHITE_WOOL), new ItemStack(Material.WHITE_WOOL), new ItemStack(Material.WHITE_WOOL), new ItemStack(Material.WHITE_WOOL), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_WOOL), new ItemStack(Material.WHITE_WOOL), new ItemStack(Material.WHITE_WOOL), new ItemStack(Material.WHITE_WOOL)},
new SlimefunItemStack(SlimefunItems.RAINBOW_WOOL, 8), new RainbowTickHandler(ColoredMaterial.WOOL))
.register(plugin);
new RainbowBlock(itemGroups.magicalGadgets, SlimefunItems.RAINBOW_GLASS, RecipeType.ANCIENT_ALTAR,
- new ItemStack[] {new ItemStack(Material.WHITE_STAINED_GLASS), new ItemStack(Material.WHITE_STAINED_GLASS), new ItemStack(Material.WHITE_STAINED_GLASS), new ItemStack(Material.WHITE_STAINED_GLASS), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_STAINED_GLASS), new ItemStack(Material.WHITE_STAINED_GLASS), new ItemStack(Material.WHITE_STAINED_GLASS), new ItemStack(Material.WHITE_STAINED_GLASS)},
+ new ItemStack[] {new ItemStack(Material.WHITE_STAINED_GLASS), new ItemStack(Material.WHITE_STAINED_GLASS), new ItemStack(Material.WHITE_STAINED_GLASS), new ItemStack(Material.WHITE_STAINED_GLASS), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_STAINED_GLASS), new ItemStack(Material.WHITE_STAINED_GLASS), new ItemStack(Material.WHITE_STAINED_GLASS), new ItemStack(Material.WHITE_STAINED_GLASS)},
new SlimefunItemStack(SlimefunItems.RAINBOW_GLASS, 8), new RainbowTickHandler(ColoredMaterial.STAINED_GLASS))
.register(plugin);
new RainbowBlock(itemGroups.magicalGadgets, SlimefunItems.RAINBOW_GLASS_PANE, RecipeType.ANCIENT_ALTAR,
- new ItemStack[] {new ItemStack(Material.WHITE_STAINED_GLASS_PANE), new ItemStack(Material.WHITE_STAINED_GLASS_PANE), new ItemStack(Material.WHITE_STAINED_GLASS_PANE), new ItemStack(Material.WHITE_STAINED_GLASS_PANE), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_STAINED_GLASS_PANE), new ItemStack(Material.WHITE_STAINED_GLASS_PANE), new ItemStack(Material.WHITE_STAINED_GLASS_PANE), new ItemStack(Material.WHITE_STAINED_GLASS_PANE)},
+ new ItemStack[] {new ItemStack(Material.WHITE_STAINED_GLASS_PANE), new ItemStack(Material.WHITE_STAINED_GLASS_PANE), new ItemStack(Material.WHITE_STAINED_GLASS_PANE), new ItemStack(Material.WHITE_STAINED_GLASS_PANE), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_STAINED_GLASS_PANE), new ItemStack(Material.WHITE_STAINED_GLASS_PANE), new ItemStack(Material.WHITE_STAINED_GLASS_PANE), new ItemStack(Material.WHITE_STAINED_GLASS_PANE)},
new SlimefunItemStack(SlimefunItems.RAINBOW_GLASS_PANE, 8), new RainbowTickHandler(ColoredMaterial.STAINED_GLASS_PANE))
.register(plugin);
new RainbowBlock(itemGroups.magicalGadgets, SlimefunItems.RAINBOW_CLAY, RecipeType.ANCIENT_ALTAR,
- new ItemStack[] {new ItemStack(Material.WHITE_TERRACOTTA), new ItemStack(Material.WHITE_TERRACOTTA), new ItemStack(Material.WHITE_TERRACOTTA), new ItemStack(Material.WHITE_TERRACOTTA), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_TERRACOTTA), new ItemStack(Material.WHITE_TERRACOTTA), new ItemStack(Material.WHITE_TERRACOTTA), new ItemStack(Material.WHITE_TERRACOTTA)},
+ new ItemStack[] {new ItemStack(Material.WHITE_TERRACOTTA), new ItemStack(Material.WHITE_TERRACOTTA), new ItemStack(Material.WHITE_TERRACOTTA), new ItemStack(Material.WHITE_TERRACOTTA), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_TERRACOTTA), new ItemStack(Material.WHITE_TERRACOTTA), new ItemStack(Material.WHITE_TERRACOTTA), new ItemStack(Material.WHITE_TERRACOTTA)},
new SlimefunItemStack(SlimefunItems.RAINBOW_CLAY, 8), new RainbowTickHandler(ColoredMaterial.TERRACOTTA))
.register(plugin);
new RainbowBlock(itemGroups.magicalGadgets, SlimefunItems.RAINBOW_CONCRETE, RecipeType.ANCIENT_ALTAR,
- new ItemStack[] {new ItemStack(Material.WHITE_CONCRETE), new ItemStack(Material.WHITE_CONCRETE), new ItemStack(Material.WHITE_CONCRETE), new ItemStack(Material.WHITE_CONCRETE), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_CONCRETE), new ItemStack(Material.WHITE_CONCRETE), new ItemStack(Material.WHITE_CONCRETE), new ItemStack(Material.WHITE_CONCRETE)},
+ new ItemStack[] {new ItemStack(Material.WHITE_CONCRETE), new ItemStack(Material.WHITE_CONCRETE), new ItemStack(Material.WHITE_CONCRETE), new ItemStack(Material.WHITE_CONCRETE), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_CONCRETE), new ItemStack(Material.WHITE_CONCRETE), new ItemStack(Material.WHITE_CONCRETE), new ItemStack(Material.WHITE_CONCRETE)},
new SlimefunItemStack(SlimefunItems.RAINBOW_CONCRETE, 8), new RainbowTickHandler(ColoredMaterial.CONCRETE))
.register(plugin);
-
+
new RainbowBlock(itemGroups.magicalGadgets, SlimefunItems.RAINBOW_GLAZED_TERRACOTTA, RecipeType.ANCIENT_ALTAR,
- new ItemStack[] {new ItemStack(Material.WHITE_GLAZED_TERRACOTTA), new ItemStack(Material.WHITE_GLAZED_TERRACOTTA), new ItemStack(Material.WHITE_GLAZED_TERRACOTTA), new ItemStack(Material.WHITE_GLAZED_TERRACOTTA), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_GLAZED_TERRACOTTA), new ItemStack(Material.WHITE_GLAZED_TERRACOTTA), new ItemStack(Material.WHITE_GLAZED_TERRACOTTA), new ItemStack(Material.WHITE_GLAZED_TERRACOTTA)},
+ new ItemStack[] {new ItemStack(Material.WHITE_GLAZED_TERRACOTTA), new ItemStack(Material.WHITE_GLAZED_TERRACOTTA), new ItemStack(Material.WHITE_GLAZED_TERRACOTTA), new ItemStack(Material.WHITE_GLAZED_TERRACOTTA), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_GLAZED_TERRACOTTA), new ItemStack(Material.WHITE_GLAZED_TERRACOTTA), new ItemStack(Material.WHITE_GLAZED_TERRACOTTA), new ItemStack(Material.WHITE_GLAZED_TERRACOTTA)},
new SlimefunItemStack(SlimefunItems.RAINBOW_GLAZED_TERRACOTTA, 8), new RainbowTickHandler(ColoredMaterial.GLAZED_TERRACOTTA))
.register(plugin);
// Christmas
new RainbowBlock(itemGroups.christmas, SlimefunItems.RAINBOW_WOOL_XMAS, RecipeType.ANCIENT_ALTAR,
- new ItemStack[] {new ItemStack(Material.RED_DYE), SlimefunItems.CHRISTMAS_COOKIE, new ItemStack(Material.GREEN_DYE), new ItemStack(Material.WHITE_WOOL), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_WOOL), new ItemStack(Material.GREEN_DYE), SlimefunItems.CHRISTMAS_COOKIE, new ItemStack(Material.RED_DYE)},
+ new ItemStack[] {new ItemStack(Material.RED_DYE), SlimefunItems.CHRISTMAS_COOKIE, new ItemStack(Material.GREEN_DYE), new ItemStack(Material.WHITE_WOOL), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_WOOL), new ItemStack(Material.GREEN_DYE), SlimefunItems.CHRISTMAS_COOKIE, new ItemStack(Material.RED_DYE)},
new SlimefunItemStack(SlimefunItems.RAINBOW_WOOL_XMAS, 2), new RainbowTickHandler(Material.RED_WOOL, Material.GREEN_WOOL))
.register(plugin);
new RainbowBlock(itemGroups.christmas, SlimefunItems.RAINBOW_GLASS_XMAS, RecipeType.ANCIENT_ALTAR,
- new ItemStack[] {new ItemStack(Material.RED_DYE), SlimefunItems.CHRISTMAS_COOKIE, new ItemStack(Material.GREEN_DYE), new ItemStack(Material.WHITE_STAINED_GLASS), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_STAINED_GLASS), new ItemStack(Material.GREEN_DYE), SlimefunItems.CHRISTMAS_COOKIE, new ItemStack(Material.RED_DYE)},
+ new ItemStack[] {new ItemStack(Material.RED_DYE), SlimefunItems.CHRISTMAS_COOKIE, new ItemStack(Material.GREEN_DYE), new ItemStack(Material.WHITE_STAINED_GLASS), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_STAINED_GLASS), new ItemStack(Material.GREEN_DYE), SlimefunItems.CHRISTMAS_COOKIE, new ItemStack(Material.RED_DYE)},
new SlimefunItemStack(SlimefunItems.RAINBOW_GLASS_XMAS, 2), new RainbowTickHandler(Material.RED_STAINED_GLASS, Material.GREEN_STAINED_GLASS))
.register(plugin);
new RainbowBlock(itemGroups.christmas, SlimefunItems.RAINBOW_GLASS_PANE_XMAS, RecipeType.ANCIENT_ALTAR,
- new ItemStack[] {new ItemStack(Material.RED_DYE), SlimefunItems.CHRISTMAS_COOKIE, new ItemStack(Material.GREEN_DYE), new ItemStack(Material.WHITE_STAINED_GLASS_PANE), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_STAINED_GLASS_PANE), new ItemStack(Material.GREEN_DYE), SlimefunItems.CHRISTMAS_COOKIE, new ItemStack(Material.RED_DYE)},
+ new ItemStack[] {new ItemStack(Material.RED_DYE), SlimefunItems.CHRISTMAS_COOKIE, new ItemStack(Material.GREEN_DYE), new ItemStack(Material.WHITE_STAINED_GLASS_PANE), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_STAINED_GLASS_PANE), new ItemStack(Material.GREEN_DYE), SlimefunItems.CHRISTMAS_COOKIE, new ItemStack(Material.RED_DYE)},
new SlimefunItemStack(SlimefunItems.RAINBOW_GLASS_PANE_XMAS, 2), new RainbowTickHandler(Material.RED_STAINED_GLASS_PANE, Material.GREEN_STAINED_GLASS_PANE))
.register(plugin);
new RainbowBlock(itemGroups.christmas, SlimefunItems.RAINBOW_CLAY_XMAS, RecipeType.ANCIENT_ALTAR,
- new ItemStack[] {new ItemStack(Material.RED_DYE), SlimefunItems.CHRISTMAS_COOKIE, new ItemStack(Material.GREEN_DYE), new ItemStack(Material.WHITE_TERRACOTTA), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_TERRACOTTA), new ItemStack(Material.GREEN_DYE), SlimefunItems.CHRISTMAS_COOKIE, new ItemStack(Material.RED_DYE)},
+ new ItemStack[] {new ItemStack(Material.RED_DYE), SlimefunItems.CHRISTMAS_COOKIE, new ItemStack(Material.GREEN_DYE), new ItemStack(Material.WHITE_TERRACOTTA), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_TERRACOTTA), new ItemStack(Material.GREEN_DYE), SlimefunItems.CHRISTMAS_COOKIE, new ItemStack(Material.RED_DYE)},
new SlimefunItemStack(SlimefunItems.RAINBOW_CLAY_XMAS, 2), new RainbowTickHandler(Material.RED_TERRACOTTA, Material.GREEN_TERRACOTTA))
.register(plugin);
new RainbowBlock(itemGroups.christmas, SlimefunItems.RAINBOW_CONCRETE_XMAS, RecipeType.ANCIENT_ALTAR,
- new ItemStack[] {new ItemStack(Material.RED_DYE), SlimefunItems.CHRISTMAS_COOKIE, new ItemStack(Material.GREEN_DYE), new ItemStack(Material.WHITE_CONCRETE), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_CONCRETE), new ItemStack(Material.GREEN_DYE), SlimefunItems.CHRISTMAS_COOKIE, new ItemStack(Material.RED_DYE)},
+ new ItemStack[] {new ItemStack(Material.RED_DYE), SlimefunItems.CHRISTMAS_COOKIE, new ItemStack(Material.GREEN_DYE), new ItemStack(Material.WHITE_CONCRETE), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_CONCRETE), new ItemStack(Material.GREEN_DYE), SlimefunItems.CHRISTMAS_COOKIE, new ItemStack(Material.RED_DYE)},
new SlimefunItemStack(SlimefunItems.RAINBOW_CONCRETE_XMAS, 2), new RainbowTickHandler(Material.RED_CONCRETE, Material.GREEN_CONCRETE))
.register(plugin);
-
+
new RainbowBlock(itemGroups.christmas, SlimefunItems.RAINBOW_GLAZED_TERRACOTTA_XMAS, RecipeType.ANCIENT_ALTAR,
- new ItemStack[] {new ItemStack(Material.RED_DYE), SlimefunItems.CHRISTMAS_COOKIE, new ItemStack(Material.GREEN_DYE), new ItemStack(Material.WHITE_GLAZED_TERRACOTTA), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_GLAZED_TERRACOTTA), new ItemStack(Material.GREEN_DYE), SlimefunItems.CHRISTMAS_COOKIE, new ItemStack(Material.RED_DYE)},
+ new ItemStack[] {new ItemStack(Material.RED_DYE), SlimefunItems.CHRISTMAS_COOKIE, new ItemStack(Material.GREEN_DYE), new ItemStack(Material.WHITE_GLAZED_TERRACOTTA), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_GLAZED_TERRACOTTA), new ItemStack(Material.GREEN_DYE), SlimefunItems.CHRISTMAS_COOKIE, new ItemStack(Material.RED_DYE)},
new SlimefunItemStack(SlimefunItems.RAINBOW_GLAZED_TERRACOTTA_XMAS, 2), new RainbowTickHandler(Material.RED_GLAZED_TERRACOTTA, Material.GREEN_GLAZED_TERRACOTTA))
.register(plugin);
-
+
// Valentines Day
new RainbowBlock(itemGroups.valentinesDay, SlimefunItems.RAINBOW_WOOL_VALENTINE, RecipeType.ANCIENT_ALTAR,
- new ItemStack[] {new ItemStack(Material.RED_DYE), new ItemStack(Material.POPPY), new ItemStack(Material.PINK_DYE), new ItemStack(Material.WHITE_WOOL), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_WOOL), new ItemStack(Material.PINK_DYE), new ItemStack(Material.POPPY), new ItemStack(Material.RED_DYE)},
+ new ItemStack[] {new ItemStack(Material.RED_DYE), new ItemStack(Material.POPPY), new ItemStack(Material.PINK_DYE), new ItemStack(Material.WHITE_WOOL), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_WOOL), new ItemStack(Material.PINK_DYE), new ItemStack(Material.POPPY), new ItemStack(Material.RED_DYE)},
new SlimefunItemStack(SlimefunItems.RAINBOW_WOOL_VALENTINE, 2), new RainbowTickHandler(Material.MAGENTA_WOOL, Material.PINK_WOOL))
.register(plugin);
new RainbowBlock(itemGroups.valentinesDay, SlimefunItems.RAINBOW_GLASS_VALENTINE, RecipeType.ANCIENT_ALTAR,
- new ItemStack[] {new ItemStack(Material.RED_DYE), new ItemStack(Material.POPPY), new ItemStack(Material.PINK_DYE), new ItemStack(Material.WHITE_STAINED_GLASS), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_STAINED_GLASS), new ItemStack(Material.PINK_DYE), new ItemStack(Material.POPPY), new ItemStack(Material.RED_DYE)},
+ new ItemStack[] {new ItemStack(Material.RED_DYE), new ItemStack(Material.POPPY), new ItemStack(Material.PINK_DYE), new ItemStack(Material.WHITE_STAINED_GLASS), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_STAINED_GLASS), new ItemStack(Material.PINK_DYE), new ItemStack(Material.POPPY), new ItemStack(Material.RED_DYE)},
new SlimefunItemStack(SlimefunItems.RAINBOW_GLASS_VALENTINE, 2), new RainbowTickHandler(Material.MAGENTA_STAINED_GLASS, Material.PINK_STAINED_GLASS))
.register(plugin);
new RainbowBlock(itemGroups.valentinesDay, SlimefunItems.RAINBOW_GLASS_PANE_VALENTINE, RecipeType.ANCIENT_ALTAR,
- new ItemStack[] {new ItemStack(Material.RED_DYE), new ItemStack(Material.POPPY), new ItemStack(Material.PINK_DYE), new ItemStack(Material.WHITE_STAINED_GLASS_PANE), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_STAINED_GLASS_PANE), new ItemStack(Material.PINK_DYE), new ItemStack(Material.POPPY), new ItemStack(Material.RED_DYE)},
+ new ItemStack[] {new ItemStack(Material.RED_DYE), new ItemStack(Material.POPPY), new ItemStack(Material.PINK_DYE), new ItemStack(Material.WHITE_STAINED_GLASS_PANE), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_STAINED_GLASS_PANE), new ItemStack(Material.PINK_DYE), new ItemStack(Material.POPPY), new ItemStack(Material.RED_DYE)},
new SlimefunItemStack(SlimefunItems.RAINBOW_GLASS_PANE_VALENTINE, 2), new RainbowTickHandler(Material.MAGENTA_STAINED_GLASS_PANE, Material.PINK_STAINED_GLASS_PANE))
.register(plugin);
new RainbowBlock(itemGroups.valentinesDay, SlimefunItems.RAINBOW_CLAY_VALENTINE, RecipeType.ANCIENT_ALTAR,
- new ItemStack[] {new ItemStack(Material.RED_DYE), new ItemStack(Material.POPPY), new ItemStack(Material.PINK_DYE), new ItemStack(Material.WHITE_TERRACOTTA), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_TERRACOTTA), new ItemStack(Material.PINK_DYE), new ItemStack(Material.POPPY), new ItemStack(Material.RED_DYE)},
+ new ItemStack[] {new ItemStack(Material.RED_DYE), new ItemStack(Material.POPPY), new ItemStack(Material.PINK_DYE), new ItemStack(Material.WHITE_TERRACOTTA), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_TERRACOTTA), new ItemStack(Material.PINK_DYE), new ItemStack(Material.POPPY), new ItemStack(Material.RED_DYE)},
new SlimefunItemStack(SlimefunItems.RAINBOW_CLAY_VALENTINE, 2), new RainbowTickHandler(Material.MAGENTA_TERRACOTTA, Material.PINK_TERRACOTTA))
.register(plugin);
-
+
new RainbowBlock(itemGroups.valentinesDay, SlimefunItems.RAINBOW_CONCRETE_VALENTINE, RecipeType.ANCIENT_ALTAR,
- new ItemStack[] {new ItemStack(Material.RED_DYE), new ItemStack(Material.POPPY), new ItemStack(Material.PINK_DYE), new ItemStack(Material.WHITE_CONCRETE), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_CONCRETE), new ItemStack(Material.PINK_DYE), new ItemStack(Material.POPPY), new ItemStack(Material.RED_DYE)},
+ new ItemStack[] {new ItemStack(Material.RED_DYE), new ItemStack(Material.POPPY), new ItemStack(Material.PINK_DYE), new ItemStack(Material.WHITE_CONCRETE), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_CONCRETE), new ItemStack(Material.PINK_DYE), new ItemStack(Material.POPPY), new ItemStack(Material.RED_DYE)},
new SlimefunItemStack(SlimefunItems.RAINBOW_CONCRETE_VALENTINE, 2), new RainbowTickHandler(Material.MAGENTA_CONCRETE, Material.PINK_CONCRETE))
.register(plugin);
-
+
new RainbowBlock(itemGroups.valentinesDay, SlimefunItems.RAINBOW_GLAZED_TERRACOTTA_VALENTINE, RecipeType.ANCIENT_ALTAR,
- new ItemStack[] {new ItemStack(Material.RED_DYE), new ItemStack(Material.POPPY), new ItemStack(Material.PINK_DYE), new ItemStack(Material.WHITE_GLAZED_TERRACOTTA), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_GLAZED_TERRACOTTA), new ItemStack(Material.PINK_DYE), new ItemStack(Material.POPPY), new ItemStack(Material.RED_DYE)},
+ new ItemStack[] {new ItemStack(Material.RED_DYE), new ItemStack(Material.POPPY), new ItemStack(Material.PINK_DYE), new ItemStack(Material.WHITE_GLAZED_TERRACOTTA), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_GLAZED_TERRACOTTA), new ItemStack(Material.PINK_DYE), new ItemStack(Material.POPPY), new ItemStack(Material.RED_DYE)},
new SlimefunItemStack(SlimefunItems.RAINBOW_GLAZED_TERRACOTTA_VALENTINE, 2), new RainbowTickHandler(Material.MAGENTA_GLAZED_TERRACOTTA, Material.PINK_GLAZED_TERRACOTTA))
.register(plugin);
// Halloween
-
+
new RainbowBlock(itemGroups.halloween, SlimefunItems.RAINBOW_WOOL_HALLOWEEN, RecipeType.ANCIENT_ALTAR,
- new ItemStack[] {new ItemStack(Material.ORANGE_DYE), new ItemStack(Material.PUMPKIN), new ItemStack(Material.BLACK_DYE), new ItemStack(Material.WHITE_WOOL), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_WOOL), new ItemStack(Material.BLACK_DYE), new ItemStack(Material.PUMPKIN), new ItemStack(Material.ORANGE_DYE)},
+ new ItemStack[] {new ItemStack(Material.ORANGE_DYE), new ItemStack(Material.PUMPKIN), new ItemStack(Material.BLACK_DYE), new ItemStack(Material.WHITE_WOOL), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_WOOL), new ItemStack(Material.BLACK_DYE), new ItemStack(Material.PUMPKIN), new ItemStack(Material.ORANGE_DYE)},
new SlimefunItemStack(SlimefunItems.RAINBOW_WOOL_HALLOWEEN, 2), new RainbowTickHandler(Material.ORANGE_WOOL, Material.BLACK_WOOL))
.register(plugin);
new RainbowBlock(itemGroups.halloween, SlimefunItems.RAINBOW_GLASS_HALLOWEEN, RecipeType.ANCIENT_ALTAR,
- new ItemStack[] {new ItemStack(Material.ORANGE_DYE), new ItemStack(Material.PUMPKIN), new ItemStack(Material.BLACK_DYE), new ItemStack(Material.WHITE_STAINED_GLASS), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_STAINED_GLASS), new ItemStack(Material.BLACK_DYE), new ItemStack(Material.PUMPKIN), new ItemStack(Material.ORANGE_DYE)},
+ new ItemStack[] {new ItemStack(Material.ORANGE_DYE), new ItemStack(Material.PUMPKIN), new ItemStack(Material.BLACK_DYE), new ItemStack(Material.WHITE_STAINED_GLASS), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_STAINED_GLASS), new ItemStack(Material.BLACK_DYE), new ItemStack(Material.PUMPKIN), new ItemStack(Material.ORANGE_DYE)},
new SlimefunItemStack(SlimefunItems.RAINBOW_GLASS_HALLOWEEN, 2), new RainbowTickHandler(Material.ORANGE_STAINED_GLASS, Material.BLACK_STAINED_GLASS))
.register(plugin);
new RainbowBlock(itemGroups.halloween, SlimefunItems.RAINBOW_GLASS_PANE_HALLOWEEN, RecipeType.ANCIENT_ALTAR,
- new ItemStack[] {new ItemStack(Material.ORANGE_DYE), new ItemStack(Material.PUMPKIN), new ItemStack(Material.BLACK_DYE), new ItemStack(Material.WHITE_STAINED_GLASS_PANE), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_STAINED_GLASS_PANE), new ItemStack(Material.BLACK_DYE), new ItemStack(Material.PUMPKIN), new ItemStack(Material.ORANGE_DYE)},
+ new ItemStack[] {new ItemStack(Material.ORANGE_DYE), new ItemStack(Material.PUMPKIN), new ItemStack(Material.BLACK_DYE), new ItemStack(Material.WHITE_STAINED_GLASS_PANE), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_STAINED_GLASS_PANE), new ItemStack(Material.BLACK_DYE), new ItemStack(Material.PUMPKIN), new ItemStack(Material.ORANGE_DYE)},
new SlimefunItemStack(SlimefunItems.RAINBOW_GLASS_PANE_HALLOWEEN, 2), new RainbowTickHandler(Material.ORANGE_STAINED_GLASS_PANE, Material.BLACK_STAINED_GLASS_PANE))
.register(plugin);
new RainbowBlock(itemGroups.halloween, SlimefunItems.RAINBOW_CLAY_HALLOWEEN, RecipeType.ANCIENT_ALTAR,
- new ItemStack[] {new ItemStack(Material.ORANGE_DYE), new ItemStack(Material.PUMPKIN), new ItemStack(Material.BLACK_DYE), new ItemStack(Material.WHITE_TERRACOTTA), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_TERRACOTTA), new ItemStack(Material.BLACK_DYE), new ItemStack(Material.PUMPKIN), new ItemStack(Material.ORANGE_DYE)},
+ new ItemStack[] {new ItemStack(Material.ORANGE_DYE), new ItemStack(Material.PUMPKIN), new ItemStack(Material.BLACK_DYE), new ItemStack(Material.WHITE_TERRACOTTA), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_TERRACOTTA), new ItemStack(Material.BLACK_DYE), new ItemStack(Material.PUMPKIN), new ItemStack(Material.ORANGE_DYE)},
new SlimefunItemStack(SlimefunItems.RAINBOW_CLAY_HALLOWEEN, 2), new RainbowTickHandler(Material.ORANGE_TERRACOTTA, Material.BLACK_TERRACOTTA))
.register(plugin);
-
+
new RainbowBlock(itemGroups.halloween, SlimefunItems.RAINBOW_CONCRETE_HALLOWEEN, RecipeType.ANCIENT_ALTAR,
- new ItemStack[] {new ItemStack(Material.ORANGE_DYE), new ItemStack(Material.PUMPKIN), new ItemStack(Material.BLACK_DYE), new ItemStack(Material.WHITE_CONCRETE), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_CONCRETE), new ItemStack(Material.BLACK_DYE), new ItemStack(Material.PUMPKIN), new ItemStack(Material.ORANGE_DYE)},
+ new ItemStack[] {new ItemStack(Material.ORANGE_DYE), new ItemStack(Material.PUMPKIN), new ItemStack(Material.BLACK_DYE), new ItemStack(Material.WHITE_CONCRETE), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_CONCRETE), new ItemStack(Material.BLACK_DYE), new ItemStack(Material.PUMPKIN), new ItemStack(Material.ORANGE_DYE)},
new SlimefunItemStack(SlimefunItems.RAINBOW_CONCRETE_HALLOWEEN, 2), new RainbowTickHandler(Material.ORANGE_CONCRETE, Material.BLACK_CONCRETE))
.register(plugin);
-
+
new RainbowBlock(itemGroups.halloween, SlimefunItems.RAINBOW_GLAZED_TERRACOTTA_HALLOWEEN, RecipeType.ANCIENT_ALTAR,
- new ItemStack[] {new ItemStack(Material.ORANGE_DYE), new ItemStack(Material.PUMPKIN), new ItemStack(Material.BLACK_DYE), new ItemStack(Material.WHITE_GLAZED_TERRACOTTA), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_GLAZED_TERRACOTTA), new ItemStack(Material.BLACK_DYE), new ItemStack(Material.PUMPKIN), new ItemStack(Material.ORANGE_DYE)},
+ new ItemStack[] {new ItemStack(Material.ORANGE_DYE), new ItemStack(Material.PUMPKIN), new ItemStack(Material.BLACK_DYE), new ItemStack(Material.WHITE_GLAZED_TERRACOTTA), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_GLAZED_TERRACOTTA), new ItemStack(Material.BLACK_DYE), new ItemStack(Material.PUMPKIN), new ItemStack(Material.ORANGE_DYE)},
new SlimefunItemStack(SlimefunItems.RAINBOW_GLAZED_TERRACOTTA_HALLOWEEN, 2), new RainbowTickHandler(Material.ORANGE_GLAZED_TERRACOTTA, Material.BLACK_GLAZED_TERRACOTTA))
.register(plugin);
new WitherProofBlock(itemGroups.technicalComponents, SlimefunItems.WITHER_PROOF_GLASS, RecipeType.ENHANCED_CRAFTING_TABLE,
- new ItemStack[] {SlimefunItems.LEAD_INGOT, SlimefunItems.WITHER_PROOF_OBSIDIAN, SlimefunItems.LEAD_INGOT, SlimefunItems.WITHER_PROOF_OBSIDIAN, SlimefunItems.HARDENED_GLASS, SlimefunItems.WITHER_PROOF_OBSIDIAN, SlimefunItems.LEAD_INGOT, SlimefunItems.WITHER_PROOF_OBSIDIAN, SlimefunItems.LEAD_INGOT},
+ new ItemStack[] {SlimefunItems.LEAD_INGOT, SlimefunItems.WITHER_PROOF_OBSIDIAN, SlimefunItems.LEAD_INGOT, SlimefunItems.WITHER_PROOF_OBSIDIAN, SlimefunItems.HARDENED_GLASS, SlimefunItems.WITHER_PROOF_OBSIDIAN, SlimefunItems.LEAD_INGOT, SlimefunItems.WITHER_PROOF_OBSIDIAN, SlimefunItems.LEAD_INGOT},
new SlimefunItemStack(SlimefunItems.WITHER_PROOF_GLASS, 4))
.register(plugin);
@@ -2275,7 +2280,7 @@ public int getEnergyConsumption() {
.register(plugin);
new TeleporterPylon(itemGroups.gps, SlimefunItems.GPS_TELEPORTER_PYLON, RecipeType.ENHANCED_CRAFTING_TABLE,
- new ItemStack[] {SlimefunItems.ZINC_INGOT, new ItemStack(Material.GLASS), SlimefunItems.ZINC_INGOT, new ItemStack(Material.GLASS), SlimefunItems.HEATING_COIL, new ItemStack(Material.GLASS), SlimefunItems.ZINC_INGOT, new ItemStack(Material.GLASS), SlimefunItems.ZINC_INGOT},
+ new ItemStack[] {SlimefunItems.ZINC_INGOT, new ItemStack(Material.GLASS), SlimefunItems.ZINC_INGOT, new ItemStack(Material.GLASS), SlimefunItems.HEATING_COIL, new ItemStack(Material.GLASS), SlimefunItems.ZINC_INGOT, new ItemStack(Material.GLASS), SlimefunItems.ZINC_INGOT},
new SlimefunItemStack(SlimefunItems.GPS_TELEPORTER_PYLON, 8))
.register(plugin);
@@ -2379,9 +2384,11 @@ public int getEnergyConsumption() {
new TreeGrowthAccelerator(itemGroups.electricity, SlimefunItems.TREE_GROWTH_ACCELERATOR, RecipeType.ENHANCED_CRAFTING_TABLE,
new ItemStack[] {null, SlimefunItems.CARBONADO, null, SlimefunItems.ELECTRIC_MOTOR, new ItemStack(Material.DIAMOND_AXE), SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.MAGNESIUM_SALT, SlimefunItems.BIG_CAPACITOR, SlimefunItems.MAGNESIUM_SALT})
.register(plugin);
-
+
new ExpCollector(itemGroups.electricity, SlimefunItems.EXP_COLLECTOR, RecipeType.ENHANCED_CRAFTING_TABLE,
new ItemStack[] {null, SlimefunItems.BLISTERING_INGOT_3, null, SlimefunItems.WITHER_PROOF_OBSIDIAN, SlimefunItems.AUTO_ENCHANTER, SlimefunItems.WITHER_PROOF_OBSIDIAN, SlimefunItems.ALUMINUM_BRONZE_INGOT, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.ALUMINUM_BRONZE_INGOT})
+ .setEnergyConsumption(10)
+ .setCapacity(1024)
.register(plugin);
new FoodComposter(itemGroups.electricity, SlimefunItems.FOOD_COMPOSTER, RecipeType.ENHANCED_CRAFTING_TABLE,
@@ -2515,7 +2522,7 @@ public int getSpeed() {
new NuclearReactor(itemGroups.electricity, SlimefunItems.NUCLEAR_REACTOR, RecipeType.ENHANCED_CRAFTING_TABLE,
new ItemStack[] {SlimefunItems.BLISTERING_INGOT_3, SlimefunItems.CARBONADO_EDGED_CAPACITOR, SlimefunItems.BLISTERING_INGOT_3, SlimefunItems.REINFORCED_PLATE, SlimefunItems.COOLING_UNIT, SlimefunItems.REINFORCED_PLATE, SlimefunItems.LEAD_INGOT, SlimefunItems.REINFORCED_PLATE, SlimefunItems.LEAD_INGOT}){
-
+
@Override
public int getEnergyProduction() {
return 250;
@@ -2525,7 +2532,7 @@ public int getEnergyProduction() {
public int getCapacity() {
return 16384;
}
-
+
}.register(plugin);
new NetherStarReactor(itemGroups.electricity, SlimefunItems.NETHER_STAR_REACTOR, RecipeType.ENHANCED_CRAFTING_TABLE,
@@ -2544,7 +2551,7 @@ public int getCapacity() {
}.register(plugin);
new UnplaceableBlock(itemGroups.cargo, SlimefunItems.CARGO_MOTOR, RecipeType.ENHANCED_CRAFTING_TABLE,
- new ItemStack[] {SlimefunItems.HARDENED_GLASS, SlimefunItems.ELECTRO_MAGNET, SlimefunItems.HARDENED_GLASS, SlimefunItems.SILVER_INGOT, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.SILVER_INGOT, SlimefunItems.HARDENED_GLASS, SlimefunItems.ELECTRO_MAGNET, SlimefunItems.HARDENED_GLASS},
+ new ItemStack[] {SlimefunItems.HARDENED_GLASS, SlimefunItems.ELECTRO_MAGNET, SlimefunItems.HARDENED_GLASS, SlimefunItems.SILVER_INGOT, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.SILVER_INGOT, SlimefunItems.HARDENED_GLASS, SlimefunItems.ELECTRO_MAGNET, SlimefunItems.HARDENED_GLASS},
new SlimefunItemStack(SlimefunItems.CARGO_MOTOR, 4))
.register(plugin);
@@ -2553,17 +2560,17 @@ public int getCapacity() {
.register(plugin);
new CargoConnectorNode(itemGroups.cargo, SlimefunItems.CARGO_CONNECTOR_NODE, RecipeType.ENHANCED_CRAFTING_TABLE,
- new ItemStack[] {SlimefunItems.BRONZE_INGOT, SlimefunItems.SILVER_INGOT, SlimefunItems.BRONZE_INGOT, SlimefunItems.SILVER_INGOT, SlimefunItems.CARGO_MOTOR, SlimefunItems.SILVER_INGOT, SlimefunItems.BRONZE_INGOT, SlimefunItems.SILVER_INGOT, SlimefunItems.BRONZE_INGOT},
+ new ItemStack[] {SlimefunItems.BRONZE_INGOT, SlimefunItems.SILVER_INGOT, SlimefunItems.BRONZE_INGOT, SlimefunItems.SILVER_INGOT, SlimefunItems.CARGO_MOTOR, SlimefunItems.SILVER_INGOT, SlimefunItems.BRONZE_INGOT, SlimefunItems.SILVER_INGOT, SlimefunItems.BRONZE_INGOT},
new SlimefunItemStack(SlimefunItems.CARGO_CONNECTOR_NODE, 4))
.register(plugin);
new CargoInputNode(itemGroups.cargo, SlimefunItems.CARGO_INPUT_NODE, RecipeType.ENHANCED_CRAFTING_TABLE,
- new ItemStack[] {null, new ItemStack(Material.HOPPER), null, SlimefunItems.BILLON_INGOT, SlimefunItems.CARGO_CONNECTOR_NODE, SlimefunItems.BILLON_INGOT, null, new ItemStack(Material.HOPPER), null},
+ new ItemStack[] {null, new ItemStack(Material.HOPPER), null, SlimefunItems.BILLON_INGOT, SlimefunItems.CARGO_CONNECTOR_NODE, SlimefunItems.BILLON_INGOT, null, new ItemStack(Material.HOPPER), null},
new SlimefunItemStack(SlimefunItems.CARGO_INPUT_NODE, 2))
.register(plugin);
new CargoOutputNode(itemGroups.cargo, SlimefunItems.CARGO_OUTPUT_NODE, RecipeType.ENHANCED_CRAFTING_TABLE,
- new ItemStack[] {null, new ItemStack(Material.HOPPER), null, SlimefunItems.BRASS_INGOT, SlimefunItems.CARGO_CONNECTOR_NODE, SlimefunItems.BRASS_INGOT, null, new ItemStack(Material.HOPPER), null},
+ new ItemStack[] {null, new ItemStack(Material.HOPPER), null, SlimefunItems.BRASS_INGOT, SlimefunItems.CARGO_CONNECTOR_NODE, SlimefunItems.BRASS_INGOT, null, new ItemStack(Material.HOPPER), null},
new SlimefunItemStack(SlimefunItems.CARGO_OUTPUT_NODE, 2))
.register(plugin);
@@ -2625,11 +2632,11 @@ public int getCapacity() {
new WitherAssembler(itemGroups.electricity, SlimefunItems.WITHER_ASSEMBLER, RecipeType.ENHANCED_CRAFTING_TABLE,
new ItemStack[] {SlimefunItems.BLISTERING_INGOT_3, new ItemStack(Material.NETHER_STAR), SlimefunItems.BLISTERING_INGOT_3, SlimefunItems.WITHER_PROOF_OBSIDIAN, SlimefunItems.ANDROID_MEMORY_CORE, SlimefunItems.WITHER_PROOF_OBSIDIAN, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.REINFORCED_ALLOY_INGOT, SlimefunItems.CARBONADO_EDGED_CAPACITOR})
.register(plugin);
-
+
new TapeMeasure(itemGroups.usefulItems, SlimefunItems.TAPE_MEASURE, RecipeType.ENHANCED_CRAFTING_TABLE,
new ItemStack[] {SlimefunItems.SILICON, new ItemStack(Material.YELLOW_DYE), SlimefunItems.SILICON, new ItemStack(Material.YELLOW_DYE), new ItemStack(Material.STRING), new ItemStack(Material.YELLOW_DYE), SlimefunItems.GILDED_IRON, new ItemStack(Material.YELLOW_DYE), SlimefunItems.SILICON})
.register(plugin);
-
+
MinecraftVersion minecraftVersion = Slimefun.getMinecraftVersion();
new SlimefunItem(itemGroups.magicalArmor, SlimefunItems.BEE_HELMET, RecipeType.ARMOR_FORGE,
@@ -2646,7 +2653,7 @@ public int getCapacity() {
new LongFallBoots(itemGroups.magicalArmor, SlimefunItems.BEE_BOOTS, RecipeType.ARMOR_FORGE,
new ItemStack[] {null, null, null, SlimefunItems.GOLD_8K, null, SlimefunItems.GOLD_8K, new ItemStack(Material.HONEY_BLOCK), null, new ItemStack(Material.HONEY_BLOCK)},
- new PotionEffect[] {new PotionEffect(PotionEffectType.JUMP, 300, 2)},
+ new PotionEffect[] {new PotionEffect(VersionedPotionEffectType.JUMP_BOOST, 300, 2)},
SoundEffect.BEE_BOOTS_FALL_SOUND)
.register(plugin);
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/AncientAltarTask.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/AncientAltarTask.java
index b32e719efc..be256b0031 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/AncientAltarTask.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/AncientAltarTask.java
@@ -14,7 +14,6 @@
import org.bukkit.Effect;
import org.bukkit.Location;
import org.bukkit.Material;
-import org.bukkit.Particle;
import org.bukkit.SoundCategory;
import org.bukkit.block.Block;
import org.bukkit.entity.Item;
@@ -28,6 +27,7 @@
import io.github.thebusybiscuit.slimefun4.implementation.items.altar.AncientAltar;
import io.github.thebusybiscuit.slimefun4.implementation.items.altar.AncientPedestal;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.AncientAltarListener;
+import io.github.thebusybiscuit.slimefun4.utils.compatibility.VersionedParticle;
/**
* The {@link AncientAltarTask} is responsible for the animation that happens when a ritual
@@ -117,12 +117,12 @@ private boolean checkLockedItems() {
}
private void idle() {
- dropLocation.getWorld().spawnParticle(Particle.SPELL_WITCH, dropLocation, 16, 1.2F, 0F, 1.2F);
- dropLocation.getWorld().spawnParticle(Particle.FIREWORKS_SPARK, dropLocation, 8, 0.2F, 0F, 0.2F);
+ dropLocation.getWorld().spawnParticle(VersionedParticle.WITCH, dropLocation, 16, 1.2F, 0F, 1.2F);
+ dropLocation.getWorld().spawnParticle(VersionedParticle.FIREWORK, dropLocation, 8, 0.2F, 0F, 0.2F);
for (Location loc : particleLocations) {
- dropLocation.getWorld().spawnParticle(Particle.ENCHANTMENT_TABLE, loc, 16, 0.3F, 0.2F, 0.3F);
- dropLocation.getWorld().spawnParticle(Particle.CRIT_MAGIC, loc, 8, 0.3F, 0.2F, 0.3F);
+ dropLocation.getWorld().spawnParticle(VersionedParticle.ENCHANT, loc, 16, 0.3F, 0.2F, 0.3F);
+ dropLocation.getWorld().spawnParticle(VersionedParticle.ENCHANTED_HIT, loc, 8, 0.3F, 0.2F, 0.3F);
}
}
@@ -137,8 +137,8 @@ private void checkPedestal(@Nonnull Block pedestal) {
items.add(pedestalItem.getOriginalItemStack(entity));
SoundEffect.ANCIENT_ALTAR_ITEM_CHECK_SOUND.playAt(pedestal);
- dropLocation.getWorld().spawnParticle(Particle.ENCHANTMENT_TABLE, pedestal.getLocation().add(0.5, 1.5, 0.5), 16, 0.3F, 0.2F, 0.3F);
- dropLocation.getWorld().spawnParticle(Particle.CRIT_MAGIC, pedestal.getLocation().add(0.5, 1.5, 0.5), 8, 0.3F, 0.2F, 0.3F);
+ dropLocation.getWorld().spawnParticle(VersionedParticle.ENCHANT, pedestal.getLocation().add(0.5, 1.5, 0.5), 16, 0.3F, 0.2F, 0.3F);
+ dropLocation.getWorld().spawnParticle(VersionedParticle.ENCHANTED_HIT, pedestal.getLocation().add(0.5, 1.5, 0.5), 8, 0.3F, 0.2F, 0.3F);
positionLock.remove(entity);
entity.remove();
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/ArmorTask.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/ArmorTask.java
index 32141cb010..051f931460 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/ArmorTask.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/ArmorTask.java
@@ -24,10 +24,9 @@
import io.github.thebusybiscuit.slimefun4.core.attributes.ProtectionType;
import io.github.thebusybiscuit.slimefun4.core.attributes.Radioactive;
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
-import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
import io.github.thebusybiscuit.slimefun4.implementation.items.armor.SlimefunArmorPiece;
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.gadgets.SolarHelmet;
-import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
+import io.github.thebusybiscuit.slimefun4.utils.compatibility.VersionedPotionEffectType;
import io.github.thebusybiscuit.slimefun4.utils.itemstack.ItemStackWrapper;
/**
@@ -55,10 +54,10 @@ public ArmorTask(boolean radioactiveFire) {
Set effects = new HashSet<>();
effects.add(new PotionEffect(PotionEffectType.WITHER, 400, 2));
effects.add(new PotionEffect(PotionEffectType.BLINDNESS, 400, 3));
- effects.add(new PotionEffect(PotionEffectType.CONFUSION, 400, 3));
+ effects.add(new PotionEffect(VersionedPotionEffectType.NAUSEA, 400, 3));
effects.add(new PotionEffect(PotionEffectType.WEAKNESS, 400, 2));
- effects.add(new PotionEffect(PotionEffectType.SLOW, 400, 1));
- effects.add(new PotionEffect(PotionEffectType.SLOW_DIGGING, 400, 1));
+ effects.add(new PotionEffect(VersionedPotionEffectType.SLOWNESS, 400, 1));
+ effects.add(new PotionEffect(VersionedPotionEffectType.MINING_FATIGUE, 400, 1));
radiationEffects = Collections.unmodifiableSet(effects);
}
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/TickerTask.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/TickerTask.java
index cbf6e42eb1..91525994fb 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/TickerTask.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/TickerTask.java
@@ -44,6 +44,7 @@ public class TickerTask implements Runnable {
/**
* This Map holds all currently actively ticking locations.
+ * The value of this map (Set entries) MUST be thread-safe and mutable.
*/
private final Map> tickingLocations = new ConcurrentHashMap<>();
@@ -329,7 +330,7 @@ public Map> getLocations() {
public Set getLocations(@Nonnull Chunk chunk) {
Validate.notNull(chunk, "The Chunk cannot be null!");
- Set locations = tickingLocations.getOrDefault(new ChunkPosition(chunk), new HashSet<>());
+ Set locations = tickingLocations.getOrDefault(new ChunkPosition(chunk), Collections.emptySet());
return Collections.unmodifiableSet(locations);
}
@@ -343,7 +344,14 @@ public void enableTicker(@Nonnull Location l) {
Validate.notNull(l, "Location cannot be null!");
ChunkPosition chunk = new ChunkPosition(l.getWorld(), l.getBlockX() >> 4, l.getBlockZ() >> 4);
- Set newValue = new HashSet<>();
+
+ /*
+ Note that all the values in #tickingLocations must be thread-safe.
+ Thus, the choice is between the CHM KeySet or a synchronized set.
+ The CHM KeySet was chosen since it at least permits multiple concurrent
+ reads without blocking.
+ */
+ Set newValue = ConcurrentHashMap.newKeySet();
Set oldValue = tickingLocations.putIfAbsent(chunk, newValue);
/**
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/armor/RadiationTask.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/armor/RadiationTask.java
index 29ac850805..85e4c4bfe8 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/armor/RadiationTask.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/armor/RadiationTask.java
@@ -1,31 +1,30 @@
package io.github.thebusybiscuit.slimefun4.implementation.tasks.armor;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.UUID;
-
-import javax.annotation.Nonnull;
-import javax.annotation.ParametersAreNonnullByDefault;
-
-import org.bukkit.GameMode;
-import org.bukkit.entity.Player;
-import org.bukkit.inventory.ItemStack;
-
import io.github.bakedlibs.dough.common.ChatColors;
+import io.github.thebusybiscuit.slimefun4.api.events.RadiationDamageEvent;
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem;
import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile;
import io.github.thebusybiscuit.slimefun4.core.attributes.ProtectionType;
import io.github.thebusybiscuit.slimefun4.core.attributes.RadiationSymptom;
import io.github.thebusybiscuit.slimefun4.core.attributes.Radioactive;
-import io.github.thebusybiscuit.slimefun4.implementation.listeners.RadioactivityListener;
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
-import io.github.thebusybiscuit.slimefun4.implementation.items.RadioactiveItem;
+import io.github.thebusybiscuit.slimefun4.implementation.listeners.RadioactivityListener;
import io.github.thebusybiscuit.slimefun4.utils.RadiationUtils;
-
import net.md_5.bungee.api.ChatMessageType;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.ComponentBuilder;
+import org.bukkit.Bukkit;
+import org.bukkit.GameMode;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.ItemStack;
+
+import javax.annotation.Nonnull;
+import javax.annotation.ParametersAreNonnullByDefault;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
/**
* The {@link RadiationTask} handles radioactivity for
* {@link Radioactive} items.
@@ -48,13 +47,15 @@ protected void onPlayerTick(Player p, PlayerProfile profile) {
}
int exposureTotal = 0;
- if (!profile.hasFullProtectionAgainst(ProtectionType.RADIATION) && p.getGameMode() != GameMode.CREATIVE && p.getGameMode() != GameMode.SPECTATOR) {
+ if (!profile.hasFullProtectionAgainst(ProtectionType.RADIATION)
+ && p.getGameMode() != GameMode.CREATIVE
+ && p.getGameMode() != GameMode.SPECTATOR) {
for (ItemStack item : p.getInventory()) {
if (item == null || item.getType().isAir()) {
continue;
}
SlimefunItem sfItem = SlimefunItem.getByItem(item);
- if (sfItem instanceof RadioactiveItem radioactiveItem) {
+ if (sfItem instanceof Radioactive radioactiveItem) {
exposureTotal += item.getAmount() * radioactiveItem.getRadioactivity().getExposureModifier();
}
}
@@ -72,7 +73,14 @@ protected void onPlayerTick(Player p, PlayerProfile profile) {
int exposureLevelAfter = RadiationUtils.getExposure(p);
- Slimefun.runSync(() -> {
+ Slimefun.runSync(() -> {
+ RadiationDamageEvent event = new RadiationDamageEvent(p, exposureLevelAfter);
+ Bukkit.getPluginManager().callEvent(event);
+
+ if (event.isCancelled()) {
+ return;
+ }
+
for (RadiationSymptom symptom : symptoms) {
if (symptom.shouldApply(exposureLevelAfter)) {
symptom.apply(p);
@@ -81,8 +89,11 @@ protected void onPlayerTick(Player p, PlayerProfile profile) {
});
if (exposureLevelAfter > 0 || exposureLevelBefore > 0) {
- String msg = Slimefun.getLocalization().getMessage(p, "actionbar.radiation").replace("%level%", "" + exposureLevelAfter);
- BaseComponent[] components = new ComponentBuilder().append(ChatColors.color(msg)).create();
+ String msg = Slimefun.getLocalization()
+ .getMessage(p, "actionbar.radiation")
+ .replace("%level%", "" + exposureLevelAfter);
+ BaseComponent[] components =
+ new ComponentBuilder().append(ChatColors.color(msg)).create();
p.spigot().sendMessage(ChatMessageType.ACTION_BAR, components);
}
} else {
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/storage/backend/legacy/LegacyStorage.java b/src/main/java/io/github/thebusybiscuit/slimefun4/storage/backend/legacy/LegacyStorage.java
index d7981a5466..f051a3b846 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/storage/backend/legacy/LegacyStorage.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/storage/backend/legacy/LegacyStorage.java
@@ -27,6 +27,8 @@ public class LegacyStorage implements Storage {
@Override
public PlayerData loadPlayerData(@Nonnull UUID uuid) {
+ long start = System.nanoTime();
+
Config playerFile = new Config("data-storage/Slimefun/Players/" + uuid + ".yml");
// Not too sure why this is its own file
Config waypointsFile = new Config("data-storage/Slimefun/waypoints/" + uuid + ".yml");
@@ -73,12 +75,17 @@ public PlayerData loadPlayerData(@Nonnull UUID uuid) {
}
}
+ long end = System.nanoTime();
+ Slimefun.getAnalyticsService().recordPlayerProfileDataTime("legacy", true, end - start);
+
return new PlayerData(researches, backpacks, waypoints);
}
// The current design of saving all at once isn't great, this will be refined.
@Override
public void savePlayerData(@Nonnull UUID uuid, @Nonnull PlayerData data) {
+ long start = System.nanoTime();
+
Config playerFile = new Config("data-storage/Slimefun/Players/" + uuid + ".yml");
// Not too sure why this is its own file
Config waypointsFile = new Config("data-storage/Slimefun/waypoints/" + uuid + ".yml");
@@ -91,7 +98,17 @@ public void savePlayerData(@Nonnull UUID uuid, @Nonnull PlayerData data) {
playerFile.setValue("researches." + research.getID(), true);
// Remove the research if it's no longer researched
- } else if (playerFile.contains("researches." + research.getID())) {
+ // ----
+ // We have a duplicate ID (173) used for both Coal Gen and Bio Reactor
+ // If you researched the Goal Gen we would remove it on save if you didn't also have the Bio Reactor
+ // Due to the fact we would set it as researched (true in the branch above) on Coal Gen
+ // but then go into this branch and remove it if you didn't have Bio Reactor
+ // Sooooo we're gonna hack this for now while we move away from the Legacy Storage
+ // Let's make sure the user doesn't have _any_ research with this ID and _then_ remove it
+ } else if (
+ playerFile.contains("researches." + research.getID())
+ && !data.getResearches().stream().anyMatch((r) -> r.getID() == research.getID())
+ ) {
playerFile.setValue("researches." + research.getID(), null);
}
}
@@ -123,5 +140,8 @@ public void savePlayerData(@Nonnull UUID uuid, @Nonnull PlayerData data) {
// Save files
playerFile.save();
waypointsFile.save();
+
+ long end = System.nanoTime();
+ Slimefun.getAnalyticsService().recordPlayerProfileDataTime("legacy", false, end - start);
}
}
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/ChestMenuUtils.java b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/ChestMenuUtils.java
index 3df992835b..928233eb5d 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/ChestMenuUtils.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/ChestMenuUtils.java
@@ -5,9 +5,11 @@
import javax.annotation.Nonnull;
+import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ClickAction;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
+import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
@@ -43,6 +45,19 @@ private ChestMenuUtils() {}
private static final ItemStack PREV_BUTTON_INACTIVE = new SlimefunItemStack("_UI_PREVIOUS_INACTIVE", Material.BLACK_STAINED_GLASS_PANE, "&8\u21E6 Previous Page");
private static final ItemStack NEXT_BUTTON_INACTIVE = new SlimefunItemStack("_UI_NEXT_INACTIVE", Material.BLACK_STAINED_GLASS_PANE, "&8Next Page \u21E8");
+ private static final ChestMenu.AdvancedMenuClickHandler OUTPUT_HANDLER = new ChestMenu.AdvancedMenuClickHandler() {
+
+ @Override
+ public boolean onClick(Player p, int slot, ItemStack cursor, ClickAction action) {
+ return false;
+ }
+
+ @Override
+ public boolean onClick(InventoryClickEvent e, Player p, int slot, ItemStack cursor, ClickAction action) {
+ return cursor == null || cursor.getType() == null || cursor.getType() == Material.AIR;
+ }
+ };
+
private static final MenuClickHandler CLICK_HANDLER = (p, s, i, a) -> false;
public static @Nonnull ItemStack getBackground() {
@@ -69,6 +84,10 @@ private ChestMenuUtils() {}
return CLICK_HANDLER;
}
+ public static @Nonnull ChestMenu.AdvancedMenuClickHandler getDefaultOutputHandler() {
+ return OUTPUT_HANDLER;
+ }
+
public static @Nonnull ItemStack getBackButton(@Nonnull Player p, String... lore) {
return new CustomItemStack(BACK_BUTTON, "&7\u21E6 " + Slimefun.getLocalization().getMessage(p, "guide.back.title"), lore);
}
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/FireworkUtils.java b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/FireworkUtils.java
index 808c5364ce..e09851349d 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/FireworkUtils.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/FireworkUtils.java
@@ -15,6 +15,8 @@
import org.bukkit.entity.Firework;
import org.bukkit.inventory.meta.FireworkMeta;
+import io.github.thebusybiscuit.slimefun4.utils.compatibility.VersionedEntityType;
+
/**
* This is a simple utility class for spawning random and colorful {@link Firework} rockets.
*
@@ -31,6 +33,8 @@ public final class FireworkUtils {
Color.RED, Color.SILVER, Color.TEAL, Color.WHITE, Color.YELLOW
};
// @formatter:on
+
+ private static final EntityType firework = VersionedEntityType.FIREWORK;
private FireworkUtils() {}
@@ -39,7 +43,7 @@ public static void launchFirework(@Nonnull Location l, @Nonnull Color color) {
}
public static @Nonnull Firework createFirework(@Nonnull Location l, @Nonnull Color color) {
- Firework fw = (Firework) l.getWorld().spawnEntity(l, EntityType.FIREWORK);
+ Firework fw = (Firework) l.getWorld().spawnEntity(l, firework);
FireworkMeta meta = fw.getFireworkMeta();
meta.setDisplayName(ChatColor.GREEN + "Slimefun Research");
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/SlimefunUtils.java b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/SlimefunUtils.java
index 5fc3bda47f..a509b207f3 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/SlimefunUtils.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/SlimefunUtils.java
@@ -485,11 +485,24 @@ private static boolean equalsItemMeta(@Nonnull ItemMeta itemMeta, @Nonnull ItemM
return false;
}
- if (itemMeta instanceof PotionMeta && sfitemMeta instanceof PotionMeta) {
- return ((PotionMeta) itemMeta).getBasePotionData().equals(((PotionMeta) sfitemMeta).getBasePotionData());
+ if (!(itemMeta instanceof PotionMeta potionMeta) || !(sfitemMeta instanceof PotionMeta sfPotionMeta)) {
+ return true;
}
-
- return true;
+ MinecraftVersion current = Slimefun.getMinecraftVersion();
+
+ if (current.isBefore(20, 2)) {
+ // getBasePotionData pre 1.20.2
+ return potionMeta.getBasePotionData().equals(sfPotionMeta.getBasePotionData());
+ } else if (current.isBefore(20, 5)) {
+ // getBasePotionType without null check for 1.20.3 and 1.20.4
+ return potionMeta.getBasePotionType() == sfPotionMeta.getBasePotionType();
+ }
+ // check if potionMetha has a basePotionType (acting a null check for getBasePotionType
+ // on 1.20.5+
+ if (potionMeta.hasBasePotionType() != sfPotionMeta.hasBasePotionType()) {
+ return false;
+ }
+ return potionMeta.getBasePotionType() == sfPotionMeta.getBasePotionType();
}
/**
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/compatibility/VersionedEnchantment.java b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/compatibility/VersionedEnchantment.java
new file mode 100644
index 0000000000..d5063ce413
--- /dev/null
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/compatibility/VersionedEnchantment.java
@@ -0,0 +1,48 @@
+package io.github.thebusybiscuit.slimefun4.utils.compatibility;
+
+import org.bukkit.NamespacedKey;
+import org.bukkit.Registry;
+import org.bukkit.enchantments.Enchantment;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+// https://hub.spigotmc.org/stash/projects/SPIGOT/repos/craftbukkit/browse/src/main/java/org/bukkit/craftbukkit/legacy/FieldRename.java?until=2a6207fe150b6165722fce94c83cc1f206620ab5&untilPath=src%2Fmain%2Fjava%2Forg%2Fbukkit%2Fcraftbukkit%2Flegacy%2FFieldRename.java#86-110
+public class VersionedEnchantment {
+
+ public static final Enchantment EFFICIENCY;
+ public static final Enchantment UNBREAKING;
+ public static final Enchantment PROTECTION;
+ public static final Enchantment SHARPNESS;
+ public static final Enchantment LUCK_OF_THE_SEA;
+ public static final Enchantment AQUA_AFFINITY;
+ public static final Enchantment FORTUNE;
+
+ static {
+ // DIG_SPEED is renamed to EFFICIENCY in 1.20.5
+ EFFICIENCY = getKey("efficiency");
+
+ // DURABILITY is renamed to UNBREAKING in 1.20.5
+ UNBREAKING = getKey("unbreaking");
+
+ // PROTECTION_ENVIRONMENTAL is renamed to PROTECTION in 1.20.5
+ PROTECTION = getKey("protection");
+
+ // DAMAGE_ALL is renamed to SHARPNESS in 1.20.5
+ SHARPNESS = getKey("sharpness");
+
+ // LUCK is renamed to LUCK_OF_THE_SEA in 1.20.5
+ LUCK_OF_THE_SEA = getKey("luck_of_the_sea");
+
+ // WATER_WORKER is renamed to AQUA_AFFINITY in 1.20.5
+ AQUA_AFFINITY = getKey("aqua_affinity");
+
+ // LOOT_BONUS_BLOCKS is renamed to FORTUNE in 1.20.5
+ FORTUNE = getKey("fortune");
+ }
+
+ @Nullable
+ private static Enchantment getKey(@Nonnull String key) {
+ return Registry.ENCHANTMENT.get(NamespacedKey.minecraft(key));
+ }
+}
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/compatibility/VersionedEntityType.java b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/compatibility/VersionedEntityType.java
new file mode 100644
index 0000000000..10ae11e803
--- /dev/null
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/compatibility/VersionedEntityType.java
@@ -0,0 +1,31 @@
+package io.github.thebusybiscuit.slimefun4.utils.compatibility;
+
+import org.bukkit.NamespacedKey;
+import org.bukkit.Registry;
+import org.bukkit.entity.EntityType;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+// https://hub.spigotmc.org/stash/projects/SPIGOT/repos/craftbukkit/browse/src/main/java/org/bukkit/craftbukkit/legacy/FieldRename.java?until=2a6207fe150b6165722fce94c83cc1f206620ab5&untilPath=src%2Fmain%2Fjava%2Forg%2Fbukkit%2Fcraftbukkit%2Flegacy%2FFieldRename.java#158-193
+public class VersionedEntityType {
+
+ public static final EntityType MOOSHROOM;
+ public static final EntityType SNOW_GOLEM;
+ public static final EntityType FIREWORK;
+
+ static {
+ // MUSHROOM_COW is renamed to MOOSHROOM in 1.20.5
+ MOOSHROOM = getKey("mooshroom");
+
+ // SNOWMAN is renamed to SNOW_GOLEM in 1.20.5
+ SNOW_GOLEM = getKey("snow_golem");
+
+ FIREWORK = getKey("firework_rocket");
+ }
+
+ @Nullable
+ private static EntityType getKey(@Nonnull String key) {
+ return Registry.ENTITY_TYPE.get(NamespacedKey.minecraft(key));
+ }
+}
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/compatibility/VersionedItemFlag.java b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/compatibility/VersionedItemFlag.java
new file mode 100644
index 0000000000..507a903a23
--- /dev/null
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/compatibility/VersionedItemFlag.java
@@ -0,0 +1,34 @@
+package io.github.thebusybiscuit.slimefun4.utils.compatibility;
+
+import java.lang.reflect.Field;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.bukkit.inventory.ItemFlag;
+
+import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
+import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
+
+public class VersionedItemFlag {
+
+ public static final ItemFlag HIDE_ADDITIONAL_TOOLTIP;
+
+ static {
+ MinecraftVersion version = Slimefun.getMinecraftVersion();
+
+ HIDE_ADDITIONAL_TOOLTIP = version.isAtLeast(MinecraftVersion.MINECRAFT_1_20_5)
+ ? ItemFlag.HIDE_ADDITIONAL_TOOLTIP
+ : getKey("HIDE_POTION_EFFECTS");
+ }
+
+ @Nullable
+ private static ItemFlag getKey(@Nonnull String key) {
+ try {
+ Field field = ItemFlag.class.getDeclaredField(key);
+ return (ItemFlag) field.get(null);
+ } catch(Exception e) {
+ return null;
+ }
+ }
+}
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/compatibility/VersionedParticle.java b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/compatibility/VersionedParticle.java
new file mode 100644
index 0000000000..fafd340cc0
--- /dev/null
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/compatibility/VersionedParticle.java
@@ -0,0 +1,78 @@
+package io.github.thebusybiscuit.slimefun4.utils.compatibility;
+
+import java.lang.reflect.Field;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.bukkit.Particle;
+
+import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
+import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
+
+// https://hub.spigotmc.org/stash/projects/SPIGOT/repos/craftbukkit/browse/src/main/java/org/bukkit/craftbukkit/legacy/FieldRename.java?until=2a6207fe150b6165722fce94c83cc1f206620ab5&untilPath=src%2Fmain%2Fjava%2Forg%2Fbukkit%2Fcraftbukkit%2Flegacy%2FFieldRename.java#281-318
+public class VersionedParticle {
+
+ public static final Particle DUST;
+ public static final Particle SMOKE;
+ public static final Particle HAPPY_VILLAGER;
+ public static final Particle ENCHANTED_HIT;
+ public static final Particle EXPLOSION;
+ public static final Particle WITCH;
+ public static final Particle FIREWORK;
+ public static final Particle ENCHANT;
+
+ static {
+ MinecraftVersion version = Slimefun.getMinecraftVersion();
+
+ // REDSTONE is renamed to DUST in 1.20.5
+ DUST = version.isAtLeast(MinecraftVersion.MINECRAFT_1_20_5)
+ ? Particle.DUST
+ : getKey("REDSTONE");
+
+ // SMOKE_NORMAL is renamed to SMOKE in 1.20.5
+ SMOKE = version.isAtLeast(MinecraftVersion.MINECRAFT_1_20_5)
+ ? Particle.SMOKE
+ : getKey("SMOKE_NORMAL");
+
+ // VILLAGER_HAPPY is renamed to HAPPY_VILLAGER in 1.20.5
+ HAPPY_VILLAGER = version.isAtLeast(MinecraftVersion.MINECRAFT_1_20_5)
+ ? Particle.HAPPY_VILLAGER
+ : getKey("VILLAGER_HAPPY");
+
+ // CRIT_MAGIC is renamed to ENCHANTED_HIT in 1.20.5
+ ENCHANTED_HIT = version.isAtLeast(MinecraftVersion.MINECRAFT_1_20_5)
+ ? Particle.ENCHANTED_HIT
+ : getKey("CRIT_MAGIC");
+
+ // EXPLOSION_LARGE is renamed to EXPLOSION in 1.20.5
+ EXPLOSION = version.isAtLeast(MinecraftVersion.MINECRAFT_1_20_5)
+ ? Particle.EXPLOSION
+ : getKey("EXPLOSION_LARGE");
+
+ // SPELL_WITCH is renamed to WITCH in 1.20.5
+ WITCH = version.isAtLeast(MinecraftVersion.MINECRAFT_1_20_5)
+ ? Particle.WITCH
+ : getKey("SPELL_WITCH");
+
+ // FIREWORKS_SPARK is renamed to FIREWORK in 1.20.5
+ FIREWORK = version.isAtLeast(MinecraftVersion.MINECRAFT_1_20_5)
+ ? Particle.FIREWORK
+ : getKey("FIREWORKS_SPARK");
+
+ // ENCHANTMENT_TABLE is renamed to ENCHANT in 1.20.5
+ ENCHANT = version.isAtLeast(MinecraftVersion.MINECRAFT_1_20_5)
+ ? Particle.ENCHANT
+ : getKey("ENCHANTMENT_TABLE");
+ }
+
+ @Nullable
+ private static Particle getKey(@Nonnull String key) {
+ try {
+ Field field = Particle.class.getDeclaredField(key);
+ return (Particle) field.get(null);
+ } catch(Exception e) {
+ return null;
+ }
+ }
+}
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/compatibility/VersionedPotionEffectType.java b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/compatibility/VersionedPotionEffectType.java
new file mode 100644
index 0000000000..f3dbe6b6d1
--- /dev/null
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/compatibility/VersionedPotionEffectType.java
@@ -0,0 +1,75 @@
+package io.github.thebusybiscuit.slimefun4.utils.compatibility;
+
+import java.lang.reflect.Field;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.bukkit.potion.PotionEffectType;
+
+import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
+import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
+
+// https://hub.spigotmc.org/stash/projects/SPIGOT/repos/craftbukkit/browse/src/main/java/org/bukkit/craftbukkit/legacy/FieldRename.java?until=2a6207fe150b6165722fce94c83cc1f206620ab5&untilPath=src%2Fmain%2Fjava%2Forg%2Fbukkit%2Fcraftbukkit%2Flegacy%2FFieldRename.java#216-228
+public class VersionedPotionEffectType {
+
+ public static final PotionEffectType SLOWNESS;
+ public static final PotionEffectType HASTE;
+ public static final PotionEffectType MINING_FATIGUE;
+ public static final PotionEffectType STRENGTH;
+ public static final PotionEffectType INSTANT_HEALTH;
+ public static final PotionEffectType INSTANT_DAMAGE;
+ public static final PotionEffectType JUMP_BOOST;
+ public static final PotionEffectType NAUSEA;
+ public static final PotionEffectType RESISTANCE;
+
+ static {
+ MinecraftVersion version = Slimefun.getMinecraftVersion();
+
+ SLOWNESS = version.isAtLeast(MinecraftVersion.MINECRAFT_1_20_5)
+ ? PotionEffectType.SLOWNESS
+ : getKey("SLOW");
+
+ HASTE = version.isAtLeast(MinecraftVersion.MINECRAFT_1_20_5)
+ ? PotionEffectType.HASTE
+ : getKey("FAST_DIGGING");
+
+ MINING_FATIGUE = version.isAtLeast(MinecraftVersion.MINECRAFT_1_20_5)
+ ? PotionEffectType.MINING_FATIGUE
+ : getKey("SLOW_DIGGING");
+
+ STRENGTH = version.isAtLeast(MinecraftVersion.MINECRAFT_1_20_5)
+ ? PotionEffectType.STRENGTH
+ : getKey("INCREASE_DAMAGE");
+
+ INSTANT_HEALTH = version.isAtLeast(MinecraftVersion.MINECRAFT_1_20_5)
+ ? PotionEffectType.INSTANT_HEALTH
+ : getKey("HEAL");
+
+ INSTANT_DAMAGE = version.isAtLeast(MinecraftVersion.MINECRAFT_1_20_5)
+ ? PotionEffectType.INSTANT_DAMAGE
+ : getKey("HARM");
+
+ JUMP_BOOST = version.isAtLeast(MinecraftVersion.MINECRAFT_1_20_5)
+ ? PotionEffectType.JUMP_BOOST
+ : getKey("JUMP");
+
+ NAUSEA = version.isAtLeast(MinecraftVersion.MINECRAFT_1_20_5)
+ ? PotionEffectType.NAUSEA
+ : getKey("CONFUSION");
+
+ RESISTANCE = version.isAtLeast(MinecraftVersion.MINECRAFT_1_20_5)
+ ? PotionEffectType.RESISTANCE
+ : getKey("DAMAGE_RESISTANCE");
+ }
+
+ @Nullable
+ private static PotionEffectType getKey(@Nonnull String key) {
+ try {
+ Field field = PotionEffectType.class.getDeclaredField(key);
+ return (PotionEffectType) field.get(null);
+ } catch(Exception e) {
+ return null;
+ }
+ }
+}
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/compatibility/VersionedPotionType.java b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/compatibility/VersionedPotionType.java
new file mode 100644
index 0000000000..1713d77baf
--- /dev/null
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/compatibility/VersionedPotionType.java
@@ -0,0 +1,55 @@
+package io.github.thebusybiscuit.slimefun4.utils.compatibility;
+
+import java.lang.reflect.Field;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.bukkit.potion.PotionType;
+
+import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
+import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
+
+// https://hub.spigotmc.org/stash/projects/SPIGOT/repos/craftbukkit/browse/src/main/java/org/bukkit/craftbukkit/legacy/FieldRename.java?until=2a6207fe150b6165722fce94c83cc1f206620ab5&untilPath=src%2Fmain%2Fjava%2Forg%2Fbukkit%2Fcraftbukkit%2Flegacy%2FFieldRename.java#242-250
+public class VersionedPotionType {
+
+ public static final PotionType LEAPING;
+ public static final PotionType SWIFTNESS;
+ public static final PotionType HEALING;
+ public static final PotionType HARMING;
+ public static final PotionType REGENERATION;
+
+ static {
+ MinecraftVersion version = Slimefun.getMinecraftVersion();
+
+ LEAPING = version.isAtLeast(MinecraftVersion.MINECRAFT_1_20_5)
+ ? PotionType.LEAPING
+ : getKey("JUMP");
+
+ SWIFTNESS = version.isAtLeast(MinecraftVersion.MINECRAFT_1_20_5)
+ ? PotionType.SWIFTNESS
+ : getKey("SPEED");
+
+ HEALING = version.isAtLeast(MinecraftVersion.MINECRAFT_1_20_5)
+ ? PotionType.HEALING
+ : getKey("INSTANT_HEAL");
+
+ HARMING = version.isAtLeast(MinecraftVersion.MINECRAFT_1_20_5)
+ ? PotionType.HARMING
+ : getKey("INSTANT_DAMAGE");
+
+ REGENERATION = version.isAtLeast(MinecraftVersion.MINECRAFT_1_20_5)
+ ? PotionType.REGENERATION
+ : getKey("REGEN");
+ }
+
+ @Nullable
+ private static PotionType getKey(@Nonnull String key) {
+ try {
+ Field field = PotionType.class.getDeclaredField(key);
+ return (PotionType) field.get(null);
+ } catch(Exception e) {
+ return null;
+ }
+ }
+}
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/itemstack/ColoredFireworkStar.java b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/itemstack/ColoredFireworkStar.java
index 17a62c352f..063d91f8d1 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/itemstack/ColoredFireworkStar.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/itemstack/ColoredFireworkStar.java
@@ -9,12 +9,12 @@
import org.bukkit.FireworkEffect;
import org.bukkit.FireworkEffect.Type;
import org.bukkit.Material;
-import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.FireworkEffectMeta;
import io.github.bakedlibs.dough.common.ChatColors;
import io.github.bakedlibs.dough.items.CustomItemStack;
+import io.github.thebusybiscuit.slimefun4.utils.compatibility.VersionedItemFlag;
/**
* This simple {@link ItemStack} implementation allows us to obtain
@@ -44,7 +44,7 @@ public ColoredFireworkStar(Color color, String name, String... lore) {
im.setLore(lines);
}
- im.addItemFlags(ItemFlag.HIDE_POTION_EFFECTS);
+ im.addItemFlags(VersionedItemFlag.HIDE_ADDITIONAL_TOOLTIP);
});
}
diff --git a/src/main/java/me/mrCookieSlime/CSCoreLibPlugin/Configuration/Config.java b/src/main/java/me/mrCookieSlime/CSCoreLibPlugin/Configuration/Config.java
index 7784370617..7cceeb6a08 100644
--- a/src/main/java/me/mrCookieSlime/CSCoreLibPlugin/Configuration/Config.java
+++ b/src/main/java/me/mrCookieSlime/CSCoreLibPlugin/Configuration/Config.java
@@ -13,10 +13,8 @@
* An old remnant of CS-CoreLib.
* This will be removed once we updated everything.
* Don't look at the code, it will be gone soon, don't worry.
- *
- * @deprecated Only used by the legacy {@link BlockStorage} system.
+ * Only used by the legacy {@link BlockStorage} system.
*/
-@Deprecated
public class Config {
private final File file;
diff --git a/src/main/java/me/mrCookieSlime/CSCoreLibPlugin/general/Inventory/ChestMenu.java b/src/main/java/me/mrCookieSlime/CSCoreLibPlugin/general/Inventory/ChestMenu.java
index 1d047d0615..d13234063c 100644
--- a/src/main/java/me/mrCookieSlime/CSCoreLibPlugin/general/Inventory/ChestMenu.java
+++ b/src/main/java/me/mrCookieSlime/CSCoreLibPlugin/general/Inventory/ChestMenu.java
@@ -16,9 +16,7 @@
* An old remnant of CS-CoreLib.
* This will be removed once we updated everything.
* Don't look at the code, it will be gone soon, don't worry.
- *
*/
-@Deprecated
public class ChestMenu {
private boolean clickable;
@@ -207,7 +205,6 @@ public ChestMenu addMenuCloseHandler(MenuCloseHandler handler) {
*
* @return The ChestMenu Instance
*/
- @Deprecated
public ChestMenu build() {
return this;
}
diff --git a/src/main/java/me/mrCookieSlime/CSCoreLibPlugin/general/Inventory/ClickAction.java b/src/main/java/me/mrCookieSlime/CSCoreLibPlugin/general/Inventory/ClickAction.java
index 2592862ff2..4ad692a6e1 100644
--- a/src/main/java/me/mrCookieSlime/CSCoreLibPlugin/general/Inventory/ClickAction.java
+++ b/src/main/java/me/mrCookieSlime/CSCoreLibPlugin/general/Inventory/ClickAction.java
@@ -4,9 +4,7 @@
* An old remnant of CS-CoreLib.
* This will be removed once we updated everything.
* Don't look at the code, it will be gone soon, don't worry.
- *
*/
-@Deprecated
public class ClickAction {
private boolean right;
diff --git a/src/main/java/me/mrCookieSlime/CSCoreLibPlugin/general/Inventory/MenuListener.java b/src/main/java/me/mrCookieSlime/CSCoreLibPlugin/general/Inventory/MenuListener.java
index 3483e5a6e8..1647e5aeee 100644
--- a/src/main/java/me/mrCookieSlime/CSCoreLibPlugin/general/Inventory/MenuListener.java
+++ b/src/main/java/me/mrCookieSlime/CSCoreLibPlugin/general/Inventory/MenuListener.java
@@ -17,12 +17,9 @@
/**
* An old {@link Listener} for CS-CoreLib
- *
- * @deprecated This is an old remnant of CS-CoreLib, the last bits of the past. They will be removed once everything is
+ * This is an old remnant of CS-CoreLib, the last bits of the past. They will be removed once everything is
* updated.
- *
*/
-@Deprecated
public class MenuListener implements Listener {
static final Map menus = new HashMap<>();
diff --git a/src/main/java/me/mrCookieSlime/CSCoreLibPlugin/package-info.java b/src/main/java/me/mrCookieSlime/CSCoreLibPlugin/package-info.java
index ca990142b2..4a7b23e254 100644
--- a/src/main/java/me/mrCookieSlime/CSCoreLibPlugin/package-info.java
+++ b/src/main/java/me/mrCookieSlime/CSCoreLibPlugin/package-info.java
@@ -1,5 +1,4 @@
/**
* Old CS-CoreLib 1.X code.
*/
-@java.lang.Deprecated
package me.mrCookieSlime.CSCoreLibPlugin;
\ No newline at end of file
diff --git a/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/abstractItems/AContainer.java b/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/abstractItems/AContainer.java
index be71fbe598..04747b4f84 100644
--- a/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/abstractItems/AContainer.java
+++ b/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/abstractItems/AContainer.java
@@ -12,8 +12,6 @@
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
-import org.bukkit.entity.Player;
-import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
@@ -37,8 +35,6 @@
import io.github.thebusybiscuit.slimefun4.utils.itemstack.ItemStackWrapper;
import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config;
-import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu.AdvancedMenuClickHandler;
-import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ClickAction;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.interfaces.InventoryBlock;
import me.mrCookieSlime.Slimefun.Objects.handlers.BlockTicker;
import me.mrCookieSlime.Slimefun.api.BlockStorage;
@@ -115,18 +111,7 @@ protected void constructMenu(BlockMenuPreset preset) {
preset.addItem(22, new CustomItemStack(Material.BLACK_STAINED_GLASS_PANE, " "), ChestMenuUtils.getEmptyClickHandler());
for (int i : getOutputSlots()) {
- preset.addMenuClickHandler(i, new AdvancedMenuClickHandler() {
-
- @Override
- public boolean onClick(Player p, int slot, ItemStack cursor, ClickAction action) {
- return false;
- }
-
- @Override
- public boolean onClick(InventoryClickEvent e, Player p, int slot, ItemStack cursor, ClickAction action) {
- return cursor == null || cursor.getType() == null || cursor.getType() == Material.AIR;
- }
- });
+ preset.addMenuClickHandler(i, ChestMenuUtils.getDefaultOutputHandler());
}
}
diff --git a/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/abstractItems/AGenerator.java b/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/abstractItems/AGenerator.java
index 0bc27e5d17..db5555f6c9 100644
--- a/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/abstractItems/AGenerator.java
+++ b/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/abstractItems/AGenerator.java
@@ -12,7 +12,6 @@
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
-import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.ItemStack;
import io.github.bakedlibs.dough.items.CustomItemStack;
@@ -35,8 +34,6 @@
import io.github.thebusybiscuit.slimefun4.utils.itemstack.ItemStackWrapper;
import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config;
-import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu.AdvancedMenuClickHandler;
-import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ClickAction;
import me.mrCookieSlime.Slimefun.api.BlockStorage;
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu;
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset;
@@ -122,18 +119,7 @@ private void constructMenu(BlockMenuPreset preset) {
}
for (int i : getOutputSlots()) {
- preset.addMenuClickHandler(i, new AdvancedMenuClickHandler() {
-
- @Override
- public boolean onClick(Player p, int slot, ItemStack cursor, ClickAction action) {
- return false;
- }
-
- @Override
- public boolean onClick(InventoryClickEvent e, Player p, int slot, ItemStack cursor, ClickAction action) {
- return cursor == null || cursor.getType() == null || cursor.getType() == Material.AIR;
- }
- });
+ preset.addMenuClickHandler(i, ChestMenuUtils.getDefaultOutputHandler());
}
preset.addItem(22, new CustomItemStack(Material.BLACK_STAINED_GLASS_PANE, " "), ChestMenuUtils.getEmptyClickHandler());
@@ -282,7 +268,7 @@ public void register(@Nonnull SlimefunAddon addon) {
if (getCapacity() < 0) {
warn("The capacity has not been configured correctly. The Item was disabled.");
- warn("Make sure to call '" + getClass().getSimpleName() + "#setEnergyCapacity(...)' before registering!");
+ warn("Make sure to call '" + getClass().getSimpleName() + "#setCapacity(...)' before registering!");
}
if (getEnergyProduction() <= 0) {
diff --git a/src/main/java/me/mrCookieSlime/Slimefun/api/BlockInfoConfig.java b/src/main/java/me/mrCookieSlime/Slimefun/api/BlockInfoConfig.java
index c2f5a821eb..448f0fbcfe 100644
--- a/src/main/java/me/mrCookieSlime/Slimefun/api/BlockInfoConfig.java
+++ b/src/main/java/me/mrCookieSlime/Slimefun/api/BlockInfoConfig.java
@@ -118,4 +118,4 @@ public String toJSON() {
return new GsonBuilder().create().toJson(data);
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/me/mrCookieSlime/Slimefun/api/BlockStorage.java b/src/main/java/me/mrCookieSlime/Slimefun/api/BlockStorage.java
index c2df4fd2c9..78c9cc90a7 100644
--- a/src/main/java/me/mrCookieSlime/Slimefun/api/BlockStorage.java
+++ b/src/main/java/me/mrCookieSlime/Slimefun/api/BlockStorage.java
@@ -35,6 +35,7 @@
import com.google.gson.JsonParser;
import com.google.gson.stream.JsonWriter;
+import io.github.bakedlibs.dough.blocks.BlockPosition;
import io.github.bakedlibs.dough.common.CommonPatterns;
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem;
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
@@ -201,7 +202,7 @@ private void loadBlock(File file, FileConfiguration cfg, String key) {
* error to the console (if enabled).
*/
if (Slimefun.getRegistry().logDuplicateBlockEntries()) {
- Slimefun.logger().log(Level.INFO, "Ignoring duplicate block @ {0}, {1}, {2} ({3} -> {4})", new Object[] { l.getBlockX(), l.getBlockY(), l.getBlockZ(), blockInfo.getString("id"), storage.get(l).getString("id") });
+ Slimefun.logger().log(Level.INFO, "Ignoring duplicate block @ %d, %d, %d (%s -> %s)".formatted(l.getBlockX(), l.getBlockY(), l.getBlockZ(), blockInfo.getString("id"), storage.get(l).getString("id")));
}
return;
@@ -513,10 +514,18 @@ public static String getLocationInfo(Location l, String key) {
return getLocationInfo(l).getString(key);
}
+ public static String getLocationInfo(BlockPosition l, String key) {
+ return getLocationInfo(l.toLocation()).getString(key);
+ }
+
public static void addBlockInfo(Location l, String key, String value) {
addBlockInfo(l, key, value, false);
}
+ public static void addBlockInfo(BlockPosition l, String key, String value) {
+ addBlockInfo(l.toLocation(), key, value, false);
+ }
+
public static void addBlockInfo(Block block, String key, String value) {
addBlockInfo(block.getLocation(), key, value);
}
@@ -525,6 +534,10 @@ public static void addBlockInfo(Block block, String key, String value, boolean u
addBlockInfo(block.getLocation(), key, value, updateTicker);
}
+ public static void addBlockInfo(BlockPosition l, String key, String value, boolean updateTicker) {
+ addBlockInfo(l.toLocation(), key, value, updateTicker);
+ }
+
public static void addBlockInfo(Location l, String key, String value, boolean updateTicker) {
Config cfg = getLocationInfo(l);
diff --git a/src/main/java/me/mrCookieSlime/package-info.java b/src/main/java/me/mrCookieSlime/package-info.java
index 2fc365aed1..d346250b2c 100644
--- a/src/main/java/me/mrCookieSlime/package-info.java
+++ b/src/main/java/me/mrCookieSlime/package-info.java
@@ -3,5 +3,4 @@
* Don't look too close at the code that lays here. It's horrible, believe me.
* Once we updated everything, all of these classes will be removed.
*/
-@java.lang.Deprecated
package me.mrCookieSlime;
\ No newline at end of file
diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml
index cb133170e4..5e36b700b7 100644
--- a/src/main/resources/config.yml
+++ b/src/main/resources/config.yml
@@ -50,6 +50,7 @@ talismans:
metrics:
auto-update: true
+ analytics: true
research-ranks:
- Chicken
diff --git a/src/main/resources/languages/de/messages.yml b/src/main/resources/languages/de/messages.yml
index 55f8ead5ae..5debea0c8e 100644
--- a/src/main/resources/languages/de/messages.yml
+++ b/src/main/resources/languages/de/messages.yml
@@ -148,6 +148,7 @@ messages:
bee-suit-slow-fall: '&eDeine Bienenflügel haben dir eine sichere Landung ermöglicht'
deprecated-item: '&4Dieses Item ist veraltet und wird bald aus Slimefun entfernt.'
researching-is-disabled: '&cDas Freischalten von Items wurde auf diesem Server deaktiviert. Alles ist bereits automatisch freigeschaltet!'
+ await-deletion: '&cDu kannst keinen Slimefun Block so kurz nach dem Abbauen eines anderen platzieren. Versuche es in Kürze erneut.'
multi-tool:
mode-change: '&bDer Modus von deinem Multi-Tool wurde geändert zu: &9%mode%'
not-shears: '&cEinMulti Tool kann nicht als Schere verwendet werden!'
diff --git a/src/main/resources/languages/en/messages.yml b/src/main/resources/languages/en/messages.yml
index 81d5115c30..77bd80895a 100644
--- a/src/main/resources/languages/en/messages.yml
+++ b/src/main/resources/languages/en/messages.yml
@@ -98,7 +98,28 @@ guide:
name: '&aIs something missing?'
lore: 'Click to add your own translation'
+ modes:
+ selected: 'Slimefun Guide Type: '
+ change: 'Click to change the type'
+ SURVIVAL_MODE: 'Survival Mode'
+ CHEAT_MODE: 'Cheat Sheet'
+
options:
+ fireworks:
+ enabled:
+ text:
+ - '&bFireworks: &aYes'
+ - ''
+ - '&7You can now toggle whether you'
+ - '&7will see fireworks upon researching an item.'
+ click: '&eClick to disable your fireworks'
+ disabled:
+ text:
+ - '&bFireworks: &4No'
+ - ''
+ - '&7You can now toggle whether you'
+ - '&7will see fireworks upon researching an item.'
+ click: '&eClick to enable your fireworks'
learning-animation:
enabled:
text:
diff --git a/src/main/resources/languages/fa/messages.yml b/src/main/resources/languages/fa/messages.yml
index 1daccfc6ff..eadfe05e13 100644
--- a/src/main/resources/languages/fa/messages.yml
+++ b/src/main/resources/languages/fa/messages.yml
@@ -109,7 +109,7 @@ android:
editor: 'ویرایش برنامه'
uploaded:
- '&bدرحال آپلود...'
- - '&aSuccessfully uploaded your script!'
+ - '&aآپلود اسکریپت کامل شد!'
languages:
default: 'پیشفرض سرور'
en: 'انگلیسی'
@@ -118,9 +118,11 @@ languages:
it: 'ایتالیایی'
es: 'اسپانیایی'
pl: 'لهستانی'
+ sv: 'سوئدی'
nl: 'هلندی'
cs: 'کشور چک'
hu: 'مجارستانی'
+ lv: 'لاتویایی'
ru: 'روسی'
zh-TW: 'چینی (تایوان)'
vi: 'ویتنامی'
diff --git a/src/main/resources/languages/he/messages.yml b/src/main/resources/languages/he/messages.yml
index a6294cdf1e..00041a9ad0 100644
--- a/src/main/resources/languages/he/messages.yml
+++ b/src/main/resources/languages/he/messages.yml
@@ -124,6 +124,8 @@ guide:
wiki: '&3ויקי עורך '
resourcepack: '&c אמן חבילת משאבים'
translator: '&9מתרגם'
+actionbar:
+ radiation: '&6רמת חשיפה לקרינה: &c%level%&7/&e100'
messages:
not-researched: '&4אין לך מספיק ידע להבין זאת. &c אתה צריך לשחרר את &f"%item%&f"'
not-enough-xp: "&4אין לך מספיק נקודות ניסיון\nכדי לפתוח את זה "
diff --git a/src/main/resources/languages/hu/messages.yml b/src/main/resources/languages/hu/messages.yml
index 4f99929461..9f135acb48 100644
--- a/src/main/resources/languages/hu/messages.yml
+++ b/src/main/resources/languages/hu/messages.yml
@@ -124,6 +124,8 @@ guide:
wiki: '&3Wiki szerkesztő'
resourcepack: '&cForráscsomag művész'
translator: '&9Fordító'
+actionbar:
+ radiation: '&6Sugárterhelési szint: &c%level%&7/&e100'
messages:
not-researched: '&4Nincs elég tudásod, hogy megértsd ezt.&cFel kel még oldanod ezt a tárgyat: &f"%item%&f"'
not-enough-xp: '&4Nincs elég XP-d ennek a feloldásához'
@@ -147,6 +149,8 @@ messages:
piglin-barter: '&4Slimefun tárgyakat nem cserélhetsz el a piglinekkel.'
bee-suit-slow-fall: '&eA Bee Wings segít neked visszatérni a földre lassan és biztonságosan'
deprecated-item: '&4Ez a tárgy elavult, és hamarosan eltávolítjuk a Slimefunból.'
+ researching-is-disabled: '&cA kutatás le van tiltva ezen a szerveren. Alapértelmezés szerint minden fel van oldva!'
+ await-deletion: '&cNem tehetsz le egy Slimefun blockot ilyen gyorsan egy másik kiütése után. Próbáld újra később.'
multi-tool:
mode-change: '&b%device% mód átállítva: &9%mode%'
not-shears: '&cA Multi Tool nem használható óllóként!'
@@ -257,6 +261,9 @@ machines:
pick-a-floor: '&3- Válassz emeletet -'
current-floor: '&eEzen az emeleten tartózkodsz:'
click-to-teleport: '&eKattints&7, hogy erre az emeletre teleportálj:'
+ enter-name: '&7Kérlek írd be a kívánt emelet nevét a Chatre. &f(Színkódok is használhatóak!)'
+ named: '&2Sikeresen elnevezted ezt az emeletet: &f%floor%'
+ editor-title: 'Lift konfigurálása'
TELEPORTER:
teleporting: '&3Teleportálás...'
teleported: '&3Teleportálva!'
@@ -272,6 +279,8 @@ machines:
waypoints: 'Útpont áttekintése'
CARGO_NODES:
must-be-placed: '&4Ládára vagy gépre kell helyezni!'
+ connected: '&2Csatlakoztatva!'
+ not-connected: '&4Nincs csatlakoztatva!'
INDUSTRIAL_MINER:
no-fuel: '&cAz Industrial Miner-ednek elfogyott az üzemanyaga! Tedd az üzemanyagot a felette lévő ládába.'
piston-facing: '&cAz Industrial Miner-edhez szükségesek dugattyúk, amik felfelé néznek!'
@@ -301,6 +310,8 @@ cauldron:
no-discoloring: '&4Nem színteleníthetsz Slimefun páncélt!'
gps:
deathpoint: '&4Halálpont: &7%date%'
+ status-online: 'ELÉRHETŐ'
+ status-offline: 'NEM ELÉRHETÔ'
waypoint:
new: '&eKérlek írd be az új útpont nevét chatre. &7(Színkódok használhatóak!)'
added: '&aSikeresen létrehoztál egy útpontot'
@@ -400,3 +411,5 @@ languages:
mk: 'Macedón'
sr: 'Szerb'
be: 'Belarusz'
+ si-LK: 'Szingaléz'
+ lt: 'Litván'
diff --git a/src/main/resources/languages/hu/researches.yml b/src/main/resources/languages/hu/researches.yml
index d911b94f33..9cd0534ced 100644
--- a/src/main/resources/languages/hu/researches.yml
+++ b/src/main/resources/languages/hu/researches.yml
@@ -259,3 +259,4 @@ slimefun:
medium_tier_auto_enchanting: Gyors Automata Varázslás és Varázslat törlése
portable_teleporter: Teleportálás bárhonnan
farmer_talisman: A Farmer talizmánja
+ rainbow_armor: Látni akarom a szivárványt magasan az égben
diff --git a/src/main/resources/languages/id/messages.yml b/src/main/resources/languages/id/messages.yml
index cc5c9157f0..d19eb84def 100644
--- a/src/main/resources/languages/id/messages.yml
+++ b/src/main/resources/languages/id/messages.yml
@@ -68,21 +68,24 @@ guide:
text:
- '&bAnimasi Pembelajaran: &aYa'
- ''
- - '&7You can now toggle whether you'
- - '&7will see information about your pondering in chat'
- - '&7upon researching an item.'
+ - '&7Sekarang Anda dapat beralih apakah Anda ingin'
+ - '&7akan melihat informasi tentang perenungan Anda dalam obrolan'
+ - '&7setelah meneliti suatu item.'
+ click: '&eKlik untuk menonaktifkan animasi pembelajaran Anda'
disabled:
text:
- '&bAnimasi Pembelajaran: &4Tidak'
- ''
- - '&7You can now toggle whether you'
- - '&7will see information about your pondering in chat'
- - '&7upon researching an item.'
+ - '&7Sekarang Anda dapat beralih apakah Anda ingin'
+ - '&7akan melihat informasi tentang perenungan Anda dalam obrolan'
+ - '&7setelah meneliti suatu item.'
+ click: '&eKlik untuk mengaktifkan animasi pembelajaran Anda'
title:
main: 'Panduan Slimefun'
settings: 'Pengaturan & Informasi'
languages: 'Pilih Bahasa Yang Anda Inginkan'
credits: 'Para Kontributor Slimefun4'
+ wiki: 'Slimefun4 Wiki'
addons: 'Addons untuk Slimefun4'
bugs: 'Laporkan masalah'
source: 'Kode sumber'
@@ -97,6 +100,7 @@ guide:
resourcepack: '&cArtis Resourcepack'
translator: '&9Penerjemah'
messages:
+ not-researched: '&4Anda tidak memiliki cukup pengetahuan untuk memahami ini. &cAnda butuh membuka &f"%item%&f" terlebih dahulu'
not-enough-xp: '&4Anda Tidak Memiliki Cukup XP untuk Membuka Ini'
unlocked: '&bAnda Telah Membuka &7"%research%"'
only-players: '&4Perintah Ini Hanya Untuk Para Pemain'
@@ -115,6 +119,9 @@ messages:
disabled-item: '&4&lBenda Ini Telah Dinonakrifkan! Bagaimana Anda Mendapatkannya?'
no-tome-yourself: '&cKamu Tidak Bisa Menggunakan &4Tome Of Knowledge &cUntuk Diri Anda Sendiri...'
multimeter: '&bEnergi Yang Telah Tersimpan: &3%stored% &b/ &3%capacity%'
+ deprecated-item: '&4Item ini telah lama tidak digunakan dan akan dihapus dari slimefun sebentar lagi.'
+ researching-is-disabled: "&cPembelajaran telah dimatikan di server ini.\nSemua ilmu terbuka gratis!"
+ await-deletion: '&cAnda tidak bisa menempatkan blok slimefun segera setelah menghancurkannya. Coba lagi sesaat kemudian.'
auto-crafting:
select: 'Pilih resep ini'
talisman:
diff --git a/src/main/resources/languages/pl/messages.yml b/src/main/resources/languages/pl/messages.yml
index 60d1775a3c..bae152e144 100644
--- a/src/main/resources/languages/pl/messages.yml
+++ b/src/main/resources/languages/pl/messages.yml
@@ -22,6 +22,8 @@ commands:
description: 'Uruchom debugowanie dla programistów'
none-running: '&7Nie ma obecnie żadnego przypadku testowego!'
disabled: '&7Wyłączono tryb debugowania.'
+placeholderapi:
+ profile-loading: 'Ładowanie...'
guide:
locked: 'Zablokowany'
work-in-progress: 'Ta funkcja nie została jeszcze ukończona!'
@@ -80,7 +82,7 @@ guide:
description:
- '&7Slimefun jest projektem open-source'
- '&7i utrzymywany przez dużą społeczność ludzi.'
- - '&7Over &e%contributors% &7people have worked on'
+ - '&7Ponad &e%contributors% &7osoby pracowały nad'
- '&7Slimefun przez te wszystkie lata.'
roles:
developer: '&6Deweloper'
diff --git a/src/main/resources/languages/pt/messages.yml b/src/main/resources/languages/pt/messages.yml
index 773cfd3682..23ddfacb86 100644
--- a/src/main/resources/languages/pt/messages.yml
+++ b/src/main/resources/languages/pt/messages.yml
@@ -52,6 +52,7 @@ guide:
miner: 'Recursos que podes obter com este Miner'
generator: 'Tipos de combustível disponíveis'
gold-pan: 'Recursos que podes obter'
+ climbing-pick: 'Superfícies que podes escalar'
pages:
previous: 'Página anterior'
next: 'Página seguinte'
@@ -79,16 +80,18 @@ guide:
text:
- '&bAnimação de descoberta: &aSim'
- ''
- - '&7You can now toggle whether you'
- - '&7will see information about your pondering in chat'
- - '&7upon researching an item.'
+ - '&7Agora podes escolher se tu'
+ - '&7vais ver informações sobre a tua ponderação no chat'
+ - '&7ao pesquisar um item.'
+ click: '&eClica para desativar a tua animação de descoberta'
disabled:
text:
- '&bAnimação de descoberta: &aNão'
- ''
- - '&7You can now toggle whether you'
- - '&7will see information about your pondering in chat'
- - '&7upon researching an item.'
+ - '&7Agora podes escolher se tu'
+ - '&7vais ver informações sobre a tua ponderação no chat'
+ - '&7ao pesquisar um item.'
+ click: '&eClica para desativar a tua animação de descoberta'
title:
main: 'Guia Slimefun'
settings: 'Configurações e informação'
@@ -110,6 +113,9 @@ guide:
resourcepack: '&cArtista de Resourcepack'
translator: '&9Tradutor'
messages:
+ not-researched: '&4Não tens conhecimento suficiente para entender isto. &cVais precisar de desbloquear &f"%item%&f"'
+ not-enough-xp: '&4Não tens XP suficiente para desbloquear isto'
+ unlocked: '&bDesbloqueaste &7"%research%"'
only-players: '&4Este comando é apenas para Jogadores'
unknown-player: '&4Jogador Desconhecido: &c%player%'
no-permission: '&4Não tens as permissões necessárias para fazer isto'
@@ -121,19 +127,45 @@ messages:
disabled-in-world: '&4&lEsse item foi desativado neste mundo'
disabled-item: '&4&lEsse item foi desativado! Como é que o conseguiste?'
piglin-barter: '&4Não podes trocar com piglins utilizando itens de Slimefun'
+ deprecated-item: '&4Este item foi descontinuado e será removido de Slimefun em breve.'
+ researching-is-disabled: '&cA pesquisa foi desativada neste servidor. Tudo está desbloqueado por padrão!'
+ await-deletion: '&cNão podes colocar um bloco do Slimefun logo após teres quebrado um. Tenta novamente.'
auto-crafting:
+ select-a-recipe: '&eBaixa-te e faz Clique Direito &7neste bloco com o item que queres craftar.'
+ recipe-set: '&aDefiniste o item para esta máquina.'
+ recipe-removed: '&eRemoveste o item desta máquina. Podes mandá-la fazer um item novo.'
+ no-recipes: '&cNão conseguimos encontrar nenhuma maneira válida de fazer o item que tu seguras.'
+ missing-chest: '&cOs Auto-Crafters teem que ser colocados sobre um baú!'
+ select: 'Selecionar esta receita'
+ temporarily-disabled: '&eEste Auto-Crafter foi temporariamente desativado. Podes reativá-lo a qualquer momento!'
+ re-enabled: '&eEste Auto-Crafter foi reativado!'
+ recipe-unavailable: |
+ &cOu este item foi desativado pelo servidor, ou ainda não desbloqueaste.
+ &7Tenta fazer o item se nunca o fizeste antes para descbloqueares a receita.
tooltips:
+ enabled:
+ - '&aEsta receita está ativada'
+ - ''
+ - '&eClique esquerdo &7para desativar a receita temporariamente'
+ - '&eClique direito &7para remover esta receita'
disabled:
- '&cEsta receita está desativada no momento'
- ''
- - '&eLeft Click &7to re-enable this recipe'
- - '&eRight Click &7to remove this recipe'
+ - '&eClique direito &7para reativar esta receita'
+ - '&eClique direito &7para remover esta receita'
+ research:
+ progress: '&7Começas a ponderar &b%research% &e(%progress%)'
no-pvp: '&cNão podes fazer pvp aqui!'
opening-guide: '&bA abrir o guia, isto pode demorar alguns segundos...'
opening-backpack: '&bA abrir a mochila, isto pode demorar alguns segundos...'
link-prompt: '&eClique aqui:'
machines:
+ pattern-not-found: '&eEu não reconheço esta receita. Coloca os itens no padrão correto no Dispenser.'
full-inventory: '&eDesculpa, o meu inventário está cheio!'
+ in-use: '&cO inventário deste bloco foi aberto por um jogador diferente.'
+ ignition-chamber-no-flint: '&cA câmara de ignição não tem isqueiros.'
+ ANCIENT_ALTAR:
+ unknown-recipe: '&4Receita desconhecida! &cUsa a receita correta!'
HOLOGRAM_PROJECTOR:
inventory-title: 'Editor de Holograma'
ELEVATOR:
@@ -150,6 +182,9 @@ machines:
GPS_CONTROL_PANEL:
transmitters: 'Transmissores'
waypoints: 'Waypoints'
+ CARGO_NODES:
+ connected: '&2Conectado!'
+ not-connected: '&4Não conectado!'
anvil:
not-working: '&4Não podes usar itens de Slimefun em uma bigorna!'
mcmmo-salvaging: '&4Não podes destruir itens do Slimefun!'
@@ -163,6 +198,9 @@ villagers:
no-trading: '&4Não podes trocar itens de Slimefun com Villagers!'
backpack:
already-open: '&cEsta mochila está aberta em outro lugar!'
+gps:
+ status-online: 'LIGADO'
+ status-offline: 'DESLIGADO'
inventory:
no-access: '&4Não tens permissão para aceder este bloco'
android:
@@ -221,6 +259,7 @@ languages:
ru: 'Russo'
sk: 'Eslovaco'
zh-CN: 'Chines (China)'
+ zh-TW: 'Chinês (Taiwan)'
vi: 'Vietnamita'
id: 'Indonésio'
el: 'Grego'
@@ -246,3 +285,5 @@ languages:
mk: 'Macedónio'
sr: 'Sérvio'
be: 'Bielorrusso'
+ si-LK: 'Cingalês'
+ lt: 'Lituano'
diff --git a/src/main/resources/languages/ru/messages.yml b/src/main/resources/languages/ru/messages.yml
index af6b255bf7..61b0dbfb5b 100644
--- a/src/main/resources/languages/ru/messages.yml
+++ b/src/main/resources/languages/ru/messages.yml
@@ -129,13 +129,28 @@ messages:
mode-change: '&bРежим «%device%» изменён на: &9%mode%'
not-shears: '&cМультиинструмент не может быть использован в качестве ножниц!'
auto-crafting:
+ select-a-recipe: '&eПрисядьте и нажмите ПКМ &7по этому блоку предметом, который хотите создать.'
+ recipe-set: '&aВы успешно установили рецепт для этой машины.'
+ recipe-removed: '&eВы успешно удалили рецепт из этой машины. Вы можете установить новый рецепт в любое время!'
+ no-recipes: '&cНе удалось найти подходящие рецепты для предмета в руке.'
+ missing-chest: '&cОтсутствует сундук! Авто-крафтеры нужно размещать над сундуком.'
select: 'Выбрать этот рецепт'
+ temporarily-disabled: '&eЭтот автоматический верстак был временно отключен. Вы можете снова включить его в любой момент!'
+ re-enabled: '&eЭтот Авто-крафтер был снова включен!'
+ recipe-unavailable: |
+ &cЭтот предмет либо отключен на сервере, либо вы еще не разблокировали его.
+ &7Попробуйте создать предмет, если вы еще не сделали этого, чтобы разблокировать рецепт.
tooltips:
enabled:
- '&cЭтот рецепт сейчас включён'
- ''
- - '&eLeft Click &7to temporarily disable the recipe'
- - '&eRight Click &7to remove this recipe'
+ - '&eЛевый клик &7для временного отключения рецепта'
+ - '&eПравый клик &7для удаления этого рецепта'
+ disabled:
+ - '&cЭтот рецепт сейчас отключён'
+ - ''
+ - '&eЛевый клик &7для включения рецепта'
+ - '&eПравый клик &7для удаления этого рецепта'
talisman:
anvil: '&a&oВаш талисман сохранил инструмент от поломки'
miner: '&a&oВаш талисман удвоил Ваш дроп'
@@ -214,6 +229,7 @@ machines:
pick-a-floor: '&3- Выберите пункт назначения -'
current-floor: '&eВаш текущий этаж:'
click-to-teleport: '&eНажмите &7для перемещения на этот этаж:'
+ editor-title: 'Настроить этот лифт'
TELEPORTER:
teleporting: '&3Телепортация…'
teleported: '&3Телепортировано!'
diff --git a/src/main/resources/languages/sv/categories.yml b/src/main/resources/languages/sv/categories.yml
index 3b31f79f7e..d82006ff2d 100644
--- a/src/main/resources/languages/sv/categories.yml
+++ b/src/main/resources/languages/sv/categories.yml
@@ -6,6 +6,7 @@ slimefun:
food: 'Mat'
basic_machines: 'Grundläggande Maskiner'
electricity: 'Energi och El'
+ androids: 'Programerbara Androider'
gps: 'GPS-baserade Maskiner'
armor: 'Rustning'
magical_items: 'Magiska Föremål'
diff --git a/src/main/resources/languages/sv/messages.yml b/src/main/resources/languages/sv/messages.yml
index 52713bca69..aa141bee30 100644
--- a/src/main/resources/languages/sv/messages.yml
+++ b/src/main/resources/languages/sv/messages.yml
@@ -13,6 +13,9 @@ commands:
description: Låser upp/återställer en spelares forskningar
reset: '&cDu har återställt %player%s kunskap'
reset-target: '&cDin kunskap har blivit återställd'
+ backpack:
+ invalid-id: '&4ID måste vara ett icke-negativt tal!'
+ backpack-does-not-exist: '&4Den angivna ryggsäcken finns inte!'
placeholderapi:
profile-loading: 'Laddar...'
guide:
@@ -36,6 +39,7 @@ guide:
miner: 'Resurser du kan få med denna Gruvarbetare'
generator: 'Tillgängliga typer av bränsle'
gold-pan: 'Resurser du kan få'
+ climbing-pick: 'Ytor som du kan klättra'
cheat:
no-multiblocks: '&4Du kan inte fuska fram Multiblocks, du måste bygga dem!'
pages:
@@ -59,6 +63,7 @@ guide:
settings: 'Inställningar & Info'
languages: 'Välj ditt föredragna språk'
credits: 'Slimefun4-medhjälpare'
+ wiki: 'Slimefun4 Wiki'
addons: 'Tilläg till Slimefun4'
bugs: 'Bugg Rapporter'
source: 'Källkoden'
@@ -91,6 +96,8 @@ messages:
disabled-item: '&4&lDetta föremål är inaktiverat! Hur fick du ens det?'
no-tome-yourself: '&cDu kan inte använda &4Tome of Knowledge &cpå dig själv'
multimeter: '&bLagrad energi: &3%stored% &b/ &3%capacity%'
+ auto-crafting:
+ select: 'Välj recept'
talisman:
anvil: '&a&oDin talisman förhindrade ditt verktyg från att gå sönder'
miner: '&a&oDin talisman dubblade precis dina gruvfynd'
diff --git a/src/main/resources/languages/sv/recipes.yml b/src/main/resources/languages/sv/recipes.yml
index ed97d539c0..83042679a5 100644
--- a/src/main/resources/languages/sv/recipes.yml
+++ b/src/main/resources/languages/sv/recipes.yml
@@ -1 +1,6 @@
---
+slimefun:
+ multiblock:
+ name: 'Multiblock'
+ oil_pump:
+ name: 'Oljepump'
diff --git a/src/main/resources/languages/tl/messages.yml b/src/main/resources/languages/tl/messages.yml
index 051a7d8bbd..08d1463bbb 100644
--- a/src/main/resources/languages/tl/messages.yml
+++ b/src/main/resources/languages/tl/messages.yml
@@ -30,6 +30,7 @@ commands:
debug:
none-running: '&7Walang kaso ng pagsubok ang kasalukuyang pinapatakbo!'
running: '&7Pinapatakbo ang debug mode kasama ang test: &6%test%'
+ disabled: '&7Hindi na tumatakbo ang debug mode.'
placeholderapi:
profile-loading: 'Naglo-load...'
guide:
@@ -80,19 +81,8 @@ guide:
options:
learning-animation:
enabled:
- text:
- - '&bKarunungang Animasyon: &aYes'
- - ''
- - '&7You can now toggle whether you'
- - '&7will see information about your pondering in chat'
- - '&7upon researching an item.'
+ click: '&eI-click para huwag paganahin ang iyong learning animation'
disabled:
- text:
- - '&bLearning Animation: &4No'
- - ''
- - '&7You can now toggle whether you'
- - '&7makikita ang impormasyon na pinagtatakahan mo sa chat'
- - '&7upon researching an item.'
click: '&eI-click para paganahin ang iyong karunungang animasyon'
title:
main: 'Gabay para sa Slimefun'
@@ -116,6 +106,7 @@ guide:
roles:
translator: '&9Tagapagsaling-wika'
messages:
+ not-researched: '&4Kulang ang iyong Kaalaman upang ito ay maintindihan. &cKailangan mo I-unlock &f"%item%&f"'
not-enough-xp: '&4Kulang ang iyong XP upang ito''y ma-unlock.'
unlocked: '&bNa-unlock mo ang &7"%research%"'
only-players: '&4Ang command na ito ay para lamang sa Players.'
diff --git a/src/main/resources/languages/tr/messages.yml b/src/main/resources/languages/tr/messages.yml
index 4cf08c8129..eb3a9f2276 100644
--- a/src/main/resources/languages/tr/messages.yml
+++ b/src/main/resources/languages/tr/messages.yml
@@ -78,6 +78,24 @@ guide:
translations:
name: '&aBir şeyler mi eksik?'
lore: 'Kendi çevirinizi eklemek için tıklayın'
+ options:
+ learning-animation:
+ enabled:
+ text:
+ - '&bÖğrenme Animasyonu: &aAçık'
+ - ''
+ - '&7İstediğiniz zaman Eşyanın bilgilerini'
+ - '&7yazdığınız zaman'
+ - '&7kanalda görmenizi sağlar.'
+ click: '&eÖğrenme animasyonunu kapatmak için tıkla'
+ disabled:
+ text:
+ - '&bÖğrenme Animasyonu: &4Kapalı'
+ - ''
+ - '&7İstediğiniz zaman Eşyanın bilgilerini'
+ - '&7yazdığınız zaman'
+ - '&7kanalda görmenizi sağlar.'
+ click: '&eÖğrenme animasyonunu açmak için tıkla'
title:
main: 'Slimefun Rehberi'
settings: 'Ayarlar & Bilgi'
@@ -127,18 +145,24 @@ messages:
mode-change: '&b%device% modül değiştirildi: &9%mode%'
not-shears: '&cBir Multi Tool makas olarak kullanılamaz!'
auto-crafting:
+ recipe-set: '&aBu makinenin tarifini başarıyla ayarladınız.'
+ recipe-removed: '&eTarifi bu makineden başarıyla kaldırdınız. İstediğiniz zaman yeni bir tarif ayarlayabilirsiniz!'
+ no-recipes: '&cTuttuğunuz öğe için geçerli herhangi bir tarif bulamadık.'
+ missing-chest: '&cKayıp göğüs! Otomatik zanaatkarlar bir sandığın üzerine yerleştirilmelidir.'
select: 'Bu tarifi seçin'
+ temporarily-disabled: '&eBu otomatik Crafter geçici olarak devre dışı bırakıldı. İstediğiniz zaman yeniden etkinleştirebilirsiniz!'
+ re-enabled: '&eBu otomatik Crafter yeniden etkinleştirildi!'
tooltips:
enabled:
- '&aBu tarif şu anda etkin'
- ''
- - '&eLeft Click &7to temporarily disable the recipe'
- - '&eRight Click &7to remove this recipe'
+ - '&eSol Tıklama &7tarifi geçici olarak devre dışı bırakmak için'
+ - '&eSağ Tıklama &7bu tarifi kaldırmak için'
disabled:
- '&cBu tarif şu anda devre dışı'
- ''
- - '&eLeft Click &7to re-enable this recipe'
- - '&eRight Click &7to remove this recipe'
+ - '&eSol Tıklama &7bu tarifi yeniden etkinleştirmek için'
+ - '&eSağ Tıklama &7bu tarifi kaldırmak için'
talisman:
anvil: '&a&oTılsım aletinizi kırılmadan kurtardı'
miner: '&a&oTılsımın madenini ikiye katladı'
@@ -235,6 +259,7 @@ machines:
waypoints: 'Yer Noktası Genel Bakışı'
CARGO_NODES:
must-be-placed: '&4Mutlaka bir sandık veya makineye bağlanmalı!'
+ connected: '&2Bağlandı!'
INDUSTRIAL_MINER:
no-fuel: '&cIndustrial Miner''ınızın yakıtı bitti! Yukarıdaki sandığa yakıt koyun.'
piston-facing: '&cIndustrial Miner''ınızın pistonu yukarıya bakmalı!'
diff --git a/src/main/resources/languages/zh-CN/messages.yml b/src/main/resources/languages/zh-CN/messages.yml
index ea7d7da109..e79b887552 100644
--- a/src/main/resources/languages/zh-CN/messages.yml
+++ b/src/main/resources/languages/zh-CN/messages.yml
@@ -81,7 +81,27 @@ guide:
translations:
name: '&a少了些什么?'
lore: '单击添加你自己的翻译'
+ modes:
+ selected: 'Slimefun 指南类型: '
+ change: '点击更改类型'
+ SURVIVAL_MODE: '生存模式'
+ CHEAT_MODE: '作弊模式'
options:
+ fireworks:
+ enabled:
+ text:
+ - '&b烟花: &a是'
+ - ''
+ - '&7你现在可以选择是否'
+ - '&7启用研究物品时的烟花。'
+ click: '&e点击关闭烟花'
+ disabled:
+ text:
+ - '&b烟花: &4否'
+ - ''
+ - '&7你现在可以选择是否'
+ - '&7启用研究物品时的烟花。'
+ click: '&e点击开启烟花'
learning-animation:
enabled:
text:
@@ -124,6 +144,8 @@ guide:
wiki: '&3Wiki 编辑者'
resourcepack: '&c材质制作者'
translator: '&9翻译者'
+actionbar:
+ radiation: '&6辐射暴露等级:&c%level%&7/&e100'
messages:
not-researched: '&4你的知识还不足以理解这个物品. &c你需要先解锁 &f"%item%"&f'
not-enough-xp: '&4你没有足够的经验来解锁这个研究'
@@ -148,6 +170,7 @@ messages:
bee-suit-slow-fall: '&e你的蜂翅将会让你安全缓降'
deprecated-item: '&4该物品已被弃用,将在不久后从 Slimefun 中移除。'
researching-is-disabled: '&c该服务器已禁用研究,所有物品都已解锁!'
+ await-deletion: '&c你不能在破坏一个 Slimefun 方块后立即放置一个 Slimefun 方块。请稍后再试。'
multi-tool:
mode-change: '&b%device% 的模式已切换为: &9%mode%'
not-shears: '&c多功能工具 (Multi Tool) 不能作为剪刀使用!'
diff --git a/src/main/resources/languages/zh-CN/researches.yml b/src/main/resources/languages/zh-CN/researches.yml
index 8a9f87f32a..07398f94e8 100644
--- a/src/main/resources/languages/zh-CN/researches.yml
+++ b/src/main/resources/languages/zh-CN/researches.yml
@@ -226,7 +226,7 @@ slimefun:
radiant_backpack: 金光闪闪的背包
auto_drier: 自动烘干机
diet_cookie: 减肥曲奇
- storm_staff: 风之法杖
+ storm_staff: 雷之法杖
soulbound_rune: 灵魂绑定符文
geo_miner: 自然资源开采机
lightning_rune: 雷电符文
@@ -259,3 +259,4 @@ slimefun:
medium_tier_auto_enchanting: 高速自动附魔/祛魔
portable_teleporter: 从任何地方传送
farmer_talisman: 农夫护身符
+ rainbow_armor: 我想看到高空中的彩虹
diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/api/events/TestTalismanActivateEvent.java b/src/test/java/io/github/thebusybiscuit/slimefun4/api/events/TestTalismanActivateEvent.java
index 94b1947cf1..40cfc61fe5 100644
--- a/src/test/java/io/github/thebusybiscuit/slimefun4/api/events/TestTalismanActivateEvent.java
+++ b/src/test/java/io/github/thebusybiscuit/slimefun4/api/events/TestTalismanActivateEvent.java
@@ -78,23 +78,20 @@ void testEventIsFired() {
activateAnvilTalisman(true, true);
server.getPluginManager().assertEventFired(TalismanActivateEvent.class, ignored -> true);
server.getPluginManager().clearEvents();
+
// Assert the normal talisman does not activate in the ender chest
activateAnvilTalisman(false, true);
- try {
- server.getPluginManager().assertEventFired(TalismanActivateEvent.class, ignored -> true);
- } catch (AssertionError ignored) {
- return; // This is expected; the event should not have fired
- }
- server.getPluginManager().clearEvents();
+ Assertions.assertThrows(
+ AssertionError.class,
+ () -> server.getPluginManager().assertEventFired(TalismanActivateEvent.class, ignored -> true)
+ );
// Assert the ender talisman does not activate in the inventory
- try {
- activateAnvilTalisman(true, false);
- server.getPluginManager().assertEventFired(TalismanActivateEvent.class, ignored -> true);
- } catch (AssertionError ignored) {
- return; // This is expected; the event should not have fired
- }
- server.getPluginManager().clearEvents();
+ activateAnvilTalisman(true, false);
+ Assertions.assertThrows(
+ AssertionError.class,
+ () -> server.getPluginManager().assertEventFired(TalismanActivateEvent.class, ignored -> true)
+ );
}
@Test
diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/core/commands/TestGuideCommand.java b/src/test/java/io/github/thebusybiscuit/slimefun4/core/commands/TestGuideCommand.java
index 0612ade074..57560503a7 100644
--- a/src/test/java/io/github/thebusybiscuit/slimefun4/core/commands/TestGuideCommand.java
+++ b/src/test/java/io/github/thebusybiscuit/slimefun4/core/commands/TestGuideCommand.java
@@ -38,9 +38,9 @@ public static void unload() {
void testCommand(boolean op) {
Player player = server.addPlayer();
player.setOp(op);
+ boolean hasPermission = player.hasPermission("slimefun.command.guide");
server.execute("slimefun", player, "guide").assertSucceeded();
-
ItemStack guide = SlimefunGuide.getItem(SlimefunGuideMode.SURVIVAL_MODE);
- Assertions.assertEquals(op, SlimefunUtils.containsSimilarItem(player.getInventory(), guide, true));
+ Assertions.assertEquals(hasPermission, SlimefunUtils.containsSimilarItem(player.getInventory(), guide, true));
}
}
diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/core/services/localization/AbstractLocaleRegexChecker.java b/src/test/java/io/github/thebusybiscuit/slimefun4/core/services/localization/AbstractLocaleRegexChecker.java
index 63eef282b4..df8668f285 100644
--- a/src/test/java/io/github/thebusybiscuit/slimefun4/core/services/localization/AbstractLocaleRegexChecker.java
+++ b/src/test/java/io/github/thebusybiscuit/slimefun4/core/services/localization/AbstractLocaleRegexChecker.java
@@ -1,8 +1,8 @@
package io.github.thebusybiscuit.slimefun4.core.services.localization;
import java.io.BufferedReader;
+import java.io.IOException;
import java.io.InputStream;
-import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.List;
@@ -16,7 +16,9 @@
import javax.annotation.ParametersAreNonnullByDefault;
import org.apache.commons.lang.Validate;
+import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.FileConfiguration;
+import org.bukkit.configuration.file.YamlConfiguration;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
@@ -50,16 +52,23 @@ public static void unload() {
@ParametersAreNonnullByDefault
@Nullable
- BufferedReader readLanguageFile(LanguagePreset lang, LanguageFile file) {
+ FileConfiguration readLanguageFile(LanguagePreset lang, LanguageFile file) throws IOException, InvalidConfigurationException {
String path = file.getFilePath(lang.getLanguageCode());
- InputStream inputStream = getClass().getResourceAsStream(path);
-
- if (inputStream == null) {
- // This file does not exist, we consider it "passed".
+ byte[] bytes;
+ try (InputStream inputStream = getClass().getResourceAsStream(path)) {
+ if (inputStream == null) {
+ // This file does not exist, we consider it "passed".
+ return null;
+ }
+ bytes = inputStream.readAllBytes();
+ }
+ String contents = new String(bytes, StandardCharsets.UTF_8);
+ if (contents.trim().equals("---")) {
return null;
}
-
- return new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
+ YamlConfiguration configuration = new YamlConfiguration();
+ configuration.loadFromString(contents);
+ return configuration;
}
@ParametersAreNonnullByDefault
diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/core/services/localization/TestColorCodes.java b/src/test/java/io/github/thebusybiscuit/slimefun4/core/services/localization/TestColorCodes.java
index 9be3d2710b..88371ac0ee 100644
--- a/src/test/java/io/github/thebusybiscuit/slimefun4/core/services/localization/TestColorCodes.java
+++ b/src/test/java/io/github/thebusybiscuit/slimefun4/core/services/localization/TestColorCodes.java
@@ -1,17 +1,15 @@
package io.github.thebusybiscuit.slimefun4.core.services.localization;
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.util.regex.Pattern;
-
-import javax.annotation.ParametersAreNonnullByDefault;
-
+import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.FileConfiguration;
-import org.bukkit.configuration.file.YamlConfiguration;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
+import javax.annotation.ParametersAreNonnullByDefault;
+import java.io.IOException;
+import java.util.regex.Pattern;
+
/**
* We need to make sure that color codes are still working properly.
*
@@ -24,7 +22,7 @@
*
* The test will catch occurences like "a& ", "b&Hello" or "7&", "5& a".
* The test will however ignore valid color codes such as "a&a".
- *
+ *
* @author TheBusyBiscuit
*
*/
@@ -38,15 +36,12 @@ class TestColorCodes extends AbstractLocaleRegexChecker {
@ParametersAreNonnullByDefault
@MethodSource("getAllLanguageFiles")
@DisplayName("Test for mistakes in color codes for Slimefun locale files")
- void testSpelling(LanguagePreset lang, LanguageFile file) throws IOException {
- try (BufferedReader reader = readLanguageFile(lang, file)) {
- if (reader == null) {
- return;
- }
-
- FileConfiguration config = YamlConfiguration.loadConfiguration(reader);
- assertNoRegexMatchesForAllEntries(lang, file, config);
+ void testSpelling(LanguagePreset lang, LanguageFile file) throws IOException, InvalidConfigurationException {
+ FileConfiguration config = readLanguageFile(lang, file);
+ if (config == null) {
+ return;
}
+ assertNoRegexMatchesForAllEntries(lang, file, config);
}
}
diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/core/services/localization/TestSlimefunSpelling.java b/src/test/java/io/github/thebusybiscuit/slimefun4/core/services/localization/TestSlimefunSpelling.java
index c33bb4c11d..dd8b62be3a 100644
--- a/src/test/java/io/github/thebusybiscuit/slimefun4/core/services/localization/TestSlimefunSpelling.java
+++ b/src/test/java/io/github/thebusybiscuit/slimefun4/core/services/localization/TestSlimefunSpelling.java
@@ -1,13 +1,12 @@
package io.github.thebusybiscuit.slimefun4.core.services.localization;
-import java.io.BufferedReader;
import java.io.IOException;
import java.util.regex.Pattern;
import javax.annotation.ParametersAreNonnullByDefault;
+import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.FileConfiguration;
-import org.bukkit.configuration.file.YamlConfiguration;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
@@ -16,7 +15,7 @@
* Your friendly neighbourhood spellcheck.
* Brought to you by our Discord bot "@WalshBot".
* No more incorrect spelling of "Slimefun".
- *
+ *
* @author TheBusyBiscuit
*
*/
@@ -30,15 +29,12 @@ class TestSlimefunSpelling extends AbstractLocaleRegexChecker {
@ParametersAreNonnullByDefault
@MethodSource("getAllLanguageFiles")
@DisplayName("Test correct spelling of Slimefun in language files")
- void testSpelling(LanguagePreset lang, LanguageFile file) throws IOException {
- try (BufferedReader reader = readLanguageFile(lang, file)) {
- if (reader == null) {
- return;
- }
-
- FileConfiguration config = YamlConfiguration.loadConfiguration(reader);
- assertNoRegexMatchesForAllEntries(lang, file, config);
+ void testSpelling(LanguagePreset lang, LanguageFile file) throws IOException, InvalidConfigurationException {
+ FileConfiguration config = readLanguageFile(lang, file);
+ if (config == null) {
+ return;
}
+ assertNoRegexMatchesForAllEntries(lang, file, config);
}
}
diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/items/TestDamageableItem.java b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/items/TestDamageableItem.java
index d7aec62eec..7a97e33cf3 100644
--- a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/items/TestDamageableItem.java
+++ b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/items/TestDamageableItem.java
@@ -20,7 +20,7 @@
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
import io.github.thebusybiscuit.slimefun4.test.TestUtilities;
import io.github.thebusybiscuit.slimefun4.test.mocks.MockDamageable;
-
+import io.github.thebusybiscuit.slimefun4.utils.compatibility.VersionedEnchantment;
import be.seeseemelk.mockbukkit.MockBukkit;
import be.seeseemelk.mockbukkit.ServerMock;
@@ -82,8 +82,8 @@ void testDamageableItemDamagesItem() {
@DisplayName("Test if DamageableItem cares about unbreaking levels")
void testDamageableItemCaresUnbreaking() {
MockDamageable noUnbreakingItem = getDummyItem("NU", true, null, null);
- MockDamageable iiiUnbreakingItem = getDummyItem("IIIU", true, Enchantment.DURABILITY, 3);
- MockDamageable xUnbreakingItem = getDummyItem("XU", true, Enchantment.DURABILITY, 10);
+ MockDamageable iiiUnbreakingItem = getDummyItem("IIIU", true, VersionedEnchantment.UNBREAKING, 3);
+ MockDamageable xUnbreakingItem = getDummyItem("XU", true, VersionedEnchantment.UNBREAKING, 10);
ItemStack noUnbreakingItemIS = noUnbreakingItem.getItem().clone();
ItemStack iiiUnbreakingItemIS = iiiUnbreakingItem.getItem().clone();
ItemStack xUnbreakingItemIS = xUnbreakingItem.getItem().clone();
diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/TestClimbingPick.java b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/TestClimbingPick.java
index 53181b2c1b..9a43bc12f5 100644
--- a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/TestClimbingPick.java
+++ b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/TestClimbingPick.java
@@ -7,7 +7,6 @@
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.BlockFace;
-import org.bukkit.enchantments.Enchantment;
import org.bukkit.inventory.ItemStack;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Assertions;
@@ -26,6 +25,7 @@
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
import io.github.thebusybiscuit.slimefun4.test.TestUtilities;
import io.github.thebusybiscuit.slimefun4.test.presets.SlimefunItemTest;
+import io.github.thebusybiscuit.slimefun4.utils.compatibility.VersionedEnchantment;
import io.github.thebusybiscuit.slimefun4.utils.tags.SlimefunTag;
import be.seeseemelk.mockbukkit.MockBukkit;
@@ -164,7 +164,7 @@ void testEfficiency() {
private ItemStack getPickWithEfficiency(@Nonnull ClimbingPick pick, int level) {
ItemStack item = pick.getItem().clone();
- item.addUnsafeEnchantment(Enchantment.DIG_SPEED, level);
+ item.addUnsafeEnchantment(VersionedEnchantment.EFFICIENCY, level);
return item;
}
}
diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestCoolerListener.java b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestCoolerListener.java
index 5bd37ce19d..e606840cbc 100644
--- a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestCoolerListener.java
+++ b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestCoolerListener.java
@@ -25,7 +25,6 @@
import io.github.thebusybiscuit.slimefun4.implementation.items.backpacks.Cooler;
import io.github.thebusybiscuit.slimefun4.implementation.items.food.Juice;
import io.github.thebusybiscuit.slimefun4.test.TestUtilities;
-
import be.seeseemelk.mockbukkit.MockBukkit;
import be.seeseemelk.mockbukkit.ServerMock;
diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/storage/backend/TestLegacyBackend.java b/src/test/java/io/github/thebusybiscuit/slimefun4/storage/backend/TestLegacyBackend.java
index c8e1916f54..98653ee5b7 100644
--- a/src/test/java/io/github/thebusybiscuit/slimefun4/storage/backend/TestLegacyBackend.java
+++ b/src/test/java/io/github/thebusybiscuit/slimefun4/storage/backend/TestLegacyBackend.java
@@ -17,6 +17,7 @@
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
@@ -52,8 +53,6 @@ public static void load() {
// within the class isn't being fired (where ItemStack and other classes are registered)
ConfigurationSerialization.registerClass(ItemStack.class);
ConfigurationSerialization.registerClass(ItemMeta.class);
-
- setupResearches();
}
@AfterAll
@@ -62,9 +61,16 @@ public static void unload() throws IOException {
FileUtils.deleteDirectory(new File("data-storage"));
}
+ @AfterEach
+ public void cleanup() {
+ Slimefun.getRegistry().getResearches().clear();
+ }
+
// Test simple loading and saving of player data
@Test
void testLoadingResearches() throws IOException {
+ setupResearches();
+
// Create a player file which we can load
UUID uuid = UUID.randomUUID();
File playerFile = new File("data-storage/Slimefun/Players/" + uuid + ".yml");
@@ -184,6 +190,8 @@ void testLoadingWaypoints() throws IOException {
@Test
void testSavingResearches() throws InterruptedException {
+ setupResearches();
+
// Create a player file which we can load
UUID uuid = UUID.randomUUID();
File playerFile = new File("data-storage/Slimefun/Players/" + uuid + ".yml");
@@ -279,6 +287,8 @@ void testSavingWaypoints() throws InterruptedException {
// Test realistic situations
@Test
void testResearchChanges() throws InterruptedException {
+ setupResearches();
+
UUID uuid = UUID.randomUUID();
File playerFile = new File("data-storage/Slimefun/Players/" + uuid + ".yml");
@@ -372,6 +382,41 @@ void testWaypointChanges() throws InterruptedException {
Assertions.assertEquals(1, assertion.getWaypoints().size());
}
+ @Test
+ void testDuplicateResearchesDontGetUnResearched() throws InterruptedException {
+ // Create a player file which we can load
+ UUID uuid = UUID.randomUUID();
+ File playerFile = new File("data-storage/Slimefun/Players/" + uuid + ".yml");
+
+ OfflinePlayer player = Bukkit.getOfflinePlayer(uuid);
+ PlayerProfile profile = TestUtilities.awaitProfile(player);
+
+ // Setup initial research
+ NamespacedKey initialKey = new NamespacedKey(plugin, "test_1");
+ Research initialResearch = new Research(initialKey, 1, "Test 1", 100);
+ initialResearch.register();
+
+ // Setup duplicate research
+ // Keep the ID as 1 but change name and key
+ NamespacedKey duplicateKey = new NamespacedKey(plugin, "test_2");
+ Research duplicateResearch = new Research(duplicateKey, 1, "Test 2", 100);
+ duplicateResearch.register();
+
+ profile.setResearched(initialResearch, true);
+
+ // Save the player data
+ LegacyStorage storage = new LegacyStorage();
+ storage.savePlayerData(uuid, profile.getPlayerData());
+
+ // Assert the file exists and data is correct
+ Assertions.assertTrue(playerFile.exists());
+ PlayerData assertion = storage.loadPlayerData(uuid);
+ // Will have both the initial and duplicate research
+ Assertions.assertEquals(2, assertion.getResearches().size());
+ Assertions.assertTrue(assertion.getResearches().contains(initialResearch));
+ Assertions.assertTrue(assertion.getResearches().contains(duplicateResearch));
+ }
+
// Utils
private static void setupResearches() {
for (int i = 0; i < 10; i++) {
diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/utils/TestMinecraftVersion.java b/src/test/java/io/github/thebusybiscuit/slimefun4/utils/TestMinecraftVersion.java
index 72beee0091..74a2622cce 100644
--- a/src/test/java/io/github/thebusybiscuit/slimefun4/utils/TestMinecraftVersion.java
+++ b/src/test/java/io/github/thebusybiscuit/slimefun4/utils/TestMinecraftVersion.java
@@ -11,11 +11,27 @@ class TestMinecraftVersion {
@Test
@DisplayName("Test if Minecraft versions match themselves")
void testMatches() {
- Assertions.assertTrue(MinecraftVersion.MINECRAFT_1_16.isMinecraftVersion(16));
- Assertions.assertTrue(MinecraftVersion.MINECRAFT_1_17.isMinecraftVersion(17));
+ Assertions.assertTrue(MinecraftVersion.MINECRAFT_1_16.isMinecraftVersion(16, -1));
+ Assertions.assertTrue(MinecraftVersion.MINECRAFT_1_17.isMinecraftVersion(17, -1));
+ Assertions.assertTrue(MinecraftVersion.MINECRAFT_1_20_5.isMinecraftVersion(20, 5));
- Assertions.assertFalse(MinecraftVersion.MINECRAFT_1_17.isMinecraftVersion(16));
- Assertions.assertFalse(MinecraftVersion.MINECRAFT_1_16.isMinecraftVersion(0));
+ Assertions.assertFalse(MinecraftVersion.MINECRAFT_1_17.isMinecraftVersion(16, -1));
+ Assertions.assertFalse(MinecraftVersion.MINECRAFT_1_16.isMinecraftVersion(0, -1));
+ Assertions.assertFalse(MinecraftVersion.MINECRAFT_1_20_5.isMinecraftVersion(20, 4));
+ }
+
+ @Test
+ @DisplayName("Test if Minecraft versions match minor versions")
+ void testMatchesMinor() {
+ Assertions.assertTrue(MinecraftVersion.MINECRAFT_1_16.isMinecraftVersion(16, 1));
+ Assertions.assertTrue(MinecraftVersion.MINECRAFT_1_16.isMinecraftVersion(16, 2));
+
+ Assertions.assertTrue(MinecraftVersion.MINECRAFT_1_20.isMinecraftVersion(20, 4));
+ Assertions.assertTrue(MinecraftVersion.MINECRAFT_1_20_5.isMinecraftVersion(20, 6));
+
+ Assertions.assertFalse(MinecraftVersion.MINECRAFT_1_20.isMinecraftVersion(20, 5));
+ Assertions.assertFalse(MinecraftVersion.MINECRAFT_1_16.isMinecraftVersion(17, 1));
+ Assertions.assertFalse(MinecraftVersion.MINECRAFT_1_20_5.isMinecraftVersion(20, 4));
}
@Test
@@ -24,6 +40,8 @@ void testAtLeast() {
Assertions.assertTrue(MinecraftVersion.MINECRAFT_1_18.isAtLeast(MinecraftVersion.MINECRAFT_1_16));
Assertions.assertTrue(MinecraftVersion.MINECRAFT_1_17.isAtLeast(MinecraftVersion.MINECRAFT_1_16));
Assertions.assertTrue(MinecraftVersion.MINECRAFT_1_17.isAtLeast(MinecraftVersion.MINECRAFT_1_17));
+ Assertions.assertTrue(MinecraftVersion.MINECRAFT_1_20.isAtLeast(MinecraftVersion.MINECRAFT_1_20));
+ Assertions.assertTrue(MinecraftVersion.MINECRAFT_1_20_5.isAtLeast(MinecraftVersion.MINECRAFT_1_20));
Assertions.assertFalse(MinecraftVersion.MINECRAFT_1_17.isAtLeast(MinecraftVersion.MINECRAFT_1_18));
}
@@ -48,6 +66,24 @@ void testIsBefore() {
Assertions.assertFalse(MinecraftVersion.MINECRAFT_1_17.isBefore(MinecraftVersion.MINECRAFT_1_16));
}
+ @Test
+ @DisplayName("Test if Minecraft versions #isBefore behaves correctly for minor versions")
+ void testIsBeforeMinor() {
+ Assertions.assertFalse(MinecraftVersion.MINECRAFT_1_18.isBefore(16, 5));
+ Assertions.assertFalse(MinecraftVersion.MINECRAFT_1_18.isBefore(17, 1));
+ Assertions.assertFalse(MinecraftVersion.MINECRAFT_1_18.isBefore(18, 0));
+ Assertions.assertTrue(MinecraftVersion.MINECRAFT_1_18.isBefore(18, 1));
+
+ Assertions.assertFalse(MinecraftVersion.MINECRAFT_1_20.isBefore(20, 0));
+ Assertions.assertTrue(MinecraftVersion.MINECRAFT_1_20.isBefore(20, 2));
+ Assertions.assertTrue(MinecraftVersion.MINECRAFT_1_20.isBefore(20, 4));
+ Assertions.assertTrue(MinecraftVersion.MINECRAFT_1_20.isBefore(20, 5));
+
+ Assertions.assertFalse(MinecraftVersion.MINECRAFT_1_20_5.isBefore(20, 4));
+ Assertions.assertFalse(MinecraftVersion.MINECRAFT_1_20_5.isBefore(20, 5));
+ Assertions.assertTrue(MinecraftVersion.MINECRAFT_1_20_5.isBefore(20, 6));
+ }
+
@Test
@DisplayName("Test correct behaviour for MinecraftVersion.UNKNOWN.isBefore(...)")
void testIsBeforeUnknown() {
diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/utils/biomes/TestBiomeMapCompatibility.java b/src/test/java/io/github/thebusybiscuit/slimefun4/utils/biomes/TestBiomeMapCompatibility.java
index cdb132d91c..99f7c6100f 100644
--- a/src/test/java/io/github/thebusybiscuit/slimefun4/utils/biomes/TestBiomeMapCompatibility.java
+++ b/src/test/java/io/github/thebusybiscuit/slimefun4/utils/biomes/TestBiomeMapCompatibility.java
@@ -34,7 +34,7 @@
/**
* This test checks if biome maps work across multiple versions of Minecraft.
* A similar test can be written for Material Tags :?
- *
+ *
* @author TheBusyBiscuit
*
*/
@@ -45,6 +45,9 @@ class TestBiomeMapCompatibility {
@BeforeAll
public static void load() {
MockBukkit.mock();
+ // Needed for JsonUtils.parseString which relies on a valid Slimefun plugin instance to determine the current
+ // MinecraftVersion
+ MockBukkit.load(Slimefun.class);
for (MinecraftVersion version : MinecraftVersion.values()) {
if (!version.isVirtual()) {
@@ -91,7 +94,7 @@ void testCompatibilities(String name, MinecraftVersion version) {
/**
* We manually specify here which biome map works on which minecraft versions.
- *
+ *
* @return A {@link Stream} of {@link Arguments} for our unit test.
*/
private static @Nonnull Stream biomeMaps() {
@@ -105,37 +108,37 @@ void testCompatibilities(String name, MinecraftVersion version) {
MinecraftVersion.MINECRAFT_1_19,
MinecraftVersion.MINECRAFT_1_20
});
-
+
testCases.put("oil_v1.16", new MinecraftVersion[] {
MinecraftVersion.MINECRAFT_1_16,
MinecraftVersion.MINECRAFT_1_17
});
-
+
testCases.put("oil_v1.18", new MinecraftVersion[] {
MinecraftVersion.MINECRAFT_1_18,
MinecraftVersion.MINECRAFT_1_19,
MinecraftVersion.MINECRAFT_1_20
});
-
+
testCases.put("salt_v1.16", new MinecraftVersion[] {
MinecraftVersion.MINECRAFT_1_16,
MinecraftVersion.MINECRAFT_1_17
});
-
+
testCases.put("salt_v1.18", new MinecraftVersion[] {
MinecraftVersion.MINECRAFT_1_18,
MinecraftVersion.MINECRAFT_1_19,
MinecraftVersion.MINECRAFT_1_20
});
-
+
testCases.put("uranium_v1.16", new MinecraftVersion[] {
MinecraftVersion.MINECRAFT_1_16
});
-
+
testCases.put("uranium_v1.17", new MinecraftVersion[] {
MinecraftVersion.MINECRAFT_1_17
});
-
+
testCases.put("uranium_v1.18", new MinecraftVersion[] {
MinecraftVersion.MINECRAFT_1_18,
MinecraftVersion.MINECRAFT_1_19,
diff --git a/src/test/resources/biomes/1.20.5+.json b/src/test/resources/biomes/1.20.5+.json
new file mode 100644
index 0000000000..dfe92f1834
--- /dev/null
+++ b/src/test/resources/biomes/1.20.5+.json
@@ -0,0 +1,67 @@
+[
+ "minecraft:ocean",
+ "minecraft:plains",
+ "minecraft:desert",
+ "minecraft:windswept_hills",
+ "minecraft:forest",
+ "minecraft:taiga",
+ "minecraft:swamp",
+ "minecraft:mangrove_swamp",
+ "minecraft:river",
+ "minecraft:nether_wastes",
+ "minecraft:the_end",
+ "minecraft:frozen_ocean",
+ "minecraft:frozen_river",
+ "minecraft:snowy_plains",
+ "minecraft:mushroom_fields",
+ "minecraft:beach",
+ "minecraft:jungle",
+ "minecraft:sparse_jungle",
+ "minecraft:deep_ocean",
+ "minecraft:stony_shore",
+ "minecraft:snowy_beach",
+ "minecraft:birch_forest",
+ "minecraft:dark_forest",
+ "minecraft:snowy_taiga",
+ "minecraft:old_growth_pine_taiga",
+ "minecraft:windswept_forest",
+ "minecraft:savanna",
+ "minecraft:savanna_plateau",
+ "minecraft:badlands",
+ "minecraft:wooded_badlands",
+ "minecraft:small_end_islands",
+ "minecraft:end_midlands",
+ "minecraft:end_highlands",
+ "minecraft:end_barrens",
+ "minecraft:warm_ocean",
+ "minecraft:lukewarm_ocean",
+ "minecraft:cold_ocean",
+ "minecraft:deep_lukewarm_ocean",
+ "minecraft:deep_cold_ocean",
+ "minecraft:deep_frozen_ocean",
+ "minecraft:the_void",
+ "minecraft:sunflower_plains",
+ "minecraft:windswept_gravelly_hills",
+ "minecraft:flower_forest",
+ "minecraft:ice_spikes",
+ "minecraft:old_growth_birch_forest",
+ "minecraft:old_growth_spruce_taiga",
+ "minecraft:windswept_savanna",
+ "minecraft:eroded_badlands",
+ "minecraft:bamboo_jungle",
+ "minecraft:soul_sand_valley",
+ "minecraft:crimson_forest",
+ "minecraft:warped_forest",
+ "minecraft:basalt_deltas",
+ "minecraft:dripstone_caves",
+ "minecraft:lush_caves",
+ "minecraft:deep_dark",
+ "minecraft:meadow",
+ "minecraft:grove",
+ "minecraft:snowy_slopes",
+ "minecraft:frozen_peaks",
+ "minecraft:jagged_peaks",
+ "minecraft:stony_peaks",
+ "minecraft:cherry_grove",
+ "minecraft:custom",
+]
\ No newline at end of file