1
mirror of https://github.com/StarWishsama/Slimefun4.git synced 2024-09-19 19:25:48 +00:00

[CI skip] Refactoring and documentation [javadocs]

This commit is contained in:
TheBusyBiscuit 2020-04-10 20:30:24 +02:00
parent e3d84de7b9
commit 65116afbe7
34 changed files with 499 additions and 183 deletions

View File

@ -65,22 +65,25 @@ public class MultiBlock {
return blocks[0] == blocks[2] && blocks[3] == blocks[5] && blocks[6] == blocks[8]; return blocks[0] == blocks[2] && blocks[3] == blocks[5] && blocks[6] == blocks[8];
} }
public Material[] getBuild() { public Material[] getStructure() {
return this.blocks; return blocks;
} }
public BlockFace getTriggerBlock() { public BlockFace getTriggerBlock() {
return this.trigger; return trigger;
} }
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if (!(obj instanceof MultiBlock)) return false; if (!(obj instanceof MultiBlock)) {
return false;
}
MultiBlock mb = (MultiBlock) obj; MultiBlock mb = (MultiBlock) obj;
if (trigger == mb.getTriggerBlock()) { if (trigger == mb.getTriggerBlock()) {
for (int i = 0; i < mb.getBuild().length; i++) { for (int i = 0; i < mb.getStructure().length; i++) {
if (!compareBlocks(blocks[i], mb.getBuild()[i])) { if (!compareBlocks(blocks[i], mb.getStructure()[i])) {
return false; return false;
} }
} }

View File

@ -90,7 +90,7 @@ public class SlimefunRegistry {
private final Map<String, ItemStack> automatedCraftingChamberRecipes = new HashMap<>(); private final Map<String, ItemStack> automatedCraftingChamberRecipes = new HashMap<>();
public void load(Config cfg) { public void load(Config cfg) {
boolean showVanillaRecipes = cfg.getBoolean("options.show-vanilla-recipes-in-guide"); boolean showVanillaRecipes = cfg.getBoolean("guide.show-vanilla-recipes");
layouts.put(SlimefunGuideLayout.CHEST, new ChestSlimefunGuide(showVanillaRecipes)); layouts.put(SlimefunGuideLayout.CHEST, new ChestSlimefunGuide(showVanillaRecipes));
layouts.put(SlimefunGuideLayout.CHEAT_SHEET, new CheatSheetSlimefunGuide()); layouts.put(SlimefunGuideLayout.CHEAT_SHEET, new CheatSheetSlimefunGuide());
@ -98,8 +98,8 @@ public class SlimefunRegistry {
researchRanks.addAll(cfg.getStringList("research-ranks")); researchRanks.addAll(cfg.getStringList("research-ranks"));
freeCreativeResearches = cfg.getBoolean("options.allow-free-creative-research"); freeCreativeResearches = cfg.getBoolean("researches.free-in-creative-mode");
researchFireworks = cfg.getBoolean("options.research-unlock-fireworks"); researchFireworks = cfg.getBoolean("researches.enable-fireworks");
} }
public boolean isAutoLoadingEnabled() { public boolean isAutoLoadingEnabled() {

View File

@ -15,8 +15,8 @@ import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
/** /**
* A {@link FlexCategory} is a {@link Category} inside the {@link SlimefunGuide} that can * A {@link FlexCategory} is a {@link Category} inside the {@link SlimefunGuide} that can
* be completely modified. * be completely modified.
* It cannot hold any {@link SlimefunItem}. * It cannot hold any {@link SlimefunItem} but can be completely overridden
* It can be completely overridden to perform any action upon being opened. * to perform any action upon being opened.
* *
* @author TheBusyBiscuit * @author TheBusyBiscuit
* *
@ -27,18 +27,18 @@ public abstract class FlexCategory extends Category {
this(key, item, 3); this(key, item, 3);
} }
public abstract boolean isVisible(Player p, PlayerProfile profile, SlimefunGuideLayout layout);
public abstract void open(Player p, PlayerProfile profile, SlimefunGuideLayout layout);
public FlexCategory(NamespacedKey key, ItemStack item, int tier) { public FlexCategory(NamespacedKey key, ItemStack item, int tier) {
super(key, item, tier); super(key, item, tier);
} }
public abstract boolean isVisible(Player p, PlayerProfile profile, SlimefunGuideLayout layout);
public abstract void open(Player p, PlayerProfile profile, SlimefunGuideLayout layout);
@Override @Override
public final boolean isHidden(Player p) { public final boolean isHidden(Player p) {
// We can stop this method right here. // We can stop this method right here.
// We provide a custom method for this. See isVisible(...) // We provide a custom method with more parameters for this. See isVisible(...)
return false; return false;
} }

View File

@ -29,6 +29,12 @@ public class SlimefunCommand implements CommandExecutor, Listener {
private final List<SubCommand> commands = new LinkedList<>(); private final List<SubCommand> commands = new LinkedList<>();
private final Map<SubCommand, Integer> commandUsage = new HashMap<>(); private final Map<SubCommand, Integer> commandUsage = new HashMap<>();
/**
* Creates a new instance of {@link SlimefunCommand}
*
* @param plugin
* The instance of our {@link SlimefunPlugin}
*/
public SlimefunCommand(SlimefunPlugin plugin) { public SlimefunCommand(SlimefunPlugin plugin) {
this.plugin = plugin; this.plugin = plugin;
} }
@ -91,7 +97,12 @@ public class SlimefunCommand implements CommandExecutor, Listener {
} }
} }
public List<String> getTabArguments() { /**
* This returns A {@link List} containing every possible {@link SubCommand} of this {@link Command}.
*
* @return A {@link List} containing every {@link SubCommand}
*/
public List<String> getSubCommandNames() {
return commands.stream().map(SubCommand::getName).collect(Collectors.toList()); return commands.stream().map(SubCommand::getName).collect(Collectors.toList());
} }

View File

@ -26,7 +26,7 @@ class SlimefunTabCompleter implements TabCompleter {
@Override @Override
public List<String> onTabComplete(CommandSender sender, Command cmd, String label, String[] args) { public List<String> onTabComplete(CommandSender sender, Command cmd, String label, String[] args) {
if (args.length == 1) { if (args.length == 1) {
return createReturnList(command.getTabArguments(), args[0]); return createReturnList(command.getSubCommandNames(), args[0]);
} }
else if (args.length == 3) { else if (args.length == 3) {
if (args[0].equalsIgnoreCase("give")) { if (args[0].equalsIgnoreCase("give")) {
@ -46,10 +46,12 @@ class SlimefunTabCompleter implements TabCompleter {
return createReturnList(suggestions, args[2]); return createReturnList(suggestions, args[2]);
} }
else { else {
// Returning null will make it fallback to the default arguments (all online players)
return null; return null;
} }
} }
else { else {
// Returning null will make it fallback to the default arguments (all online players)
return null; return null;
} }
} }

View File

@ -9,9 +9,9 @@ import org.bukkit.Bukkit;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile; import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.api.BlockStorage; import me.mrCookieSlime.Slimefun.api.BlockStorage;
import me.mrCookieSlime.Slimefun.api.Slimefun; import me.mrCookieSlime.Slimefun.api.Slimefun;
@ -26,7 +26,15 @@ public class AutoSavingService {
private int interval; private int interval;
public void start(Plugin plugin, int interval) { /**
* This method starts the {@link AutoSavingService} with the given interval.
*
* @param plugin
* The current instance of Slimefun
* @param interval
* The interval in which to run this task
*/
public void start(SlimefunPlugin plugin, int interval) {
this.interval = interval; this.interval = interval;
plugin.getServer().getScheduler().runTaskTimer(plugin, this::saveAllPlayers, 2000L, interval * 60L * 20L); plugin.getServer().getScheduler().runTaskTimer(plugin, this::saveAllPlayers, 2000L, interval * 60L * 20L);
@ -34,6 +42,10 @@ public class AutoSavingService {
} }
/**
* This method saves every {@link PlayerProfile} in memory and removes profiles
* that were markes for deletion.
*/
public void saveAllPlayers() { public void saveAllPlayers() {
Iterator<PlayerProfile> iterator = PlayerProfile.iterator(); Iterator<PlayerProfile> iterator = PlayerProfile.iterator();
int players = 0; int players = 0;
@ -46,7 +58,9 @@ public class AutoSavingService {
profile.save(); profile.save();
} }
if (profile.isMarkedForDeletion()) iterator.remove(); if (profile.isMarkedForDeletion()) {
iterator.remove();
}
} }
if (players > 0) { if (players > 0) {
@ -54,6 +68,9 @@ public class AutoSavingService {
} }
} }
/**
* This method saves the data of every {@link Block} marked dirty by {@link BlockStorage}.
*/
public void saveAllBlocks() { public void saveAllBlocks() {
Set<BlockStorage> worlds = new HashSet<>(); Set<BlockStorage> worlds = new HashSet<>();

View File

@ -2,6 +2,7 @@ package io.github.thebusybiscuit.slimefun4.core.services;
import java.util.Optional; import java.util.Optional;
import org.bukkit.Keyed;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.NamespacedKey; import org.bukkit.NamespacedKey;
import org.bukkit.block.Block; import org.bukkit.block.Block;
@ -22,7 +23,7 @@ import me.mrCookieSlime.Slimefun.SlimefunPlugin;
* @author TheBusyBiscuit * @author TheBusyBiscuit
* *
*/ */
public class BlockDataService implements PersistentDataService { public class BlockDataService implements PersistentDataService, Keyed {
private final NamespacedKey namespacedKey; private final NamespacedKey namespacedKey;
@ -30,6 +31,11 @@ public class BlockDataService implements PersistentDataService {
namespacedKey = new NamespacedKey(plugin, key); namespacedKey = new NamespacedKey(plugin, key);
} }
@Override
public NamespacedKey getKey() {
return namespacedKey;
}
/** /**
* This will store the given {@link String} inside the NBT data of the given {@link Block} * This will store the given {@link String} inside the NBT data of the given {@link Block}
* *
@ -81,7 +87,7 @@ public class BlockDataService implements PersistentDataService {
if (!SlimefunPlugin.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_14)) { if (!SlimefunPlugin.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_14)) {
return false; return false;
} }
switch (type) { switch (type) {
case PLAYER_HEAD: case PLAYER_HEAD:
case PLAYER_WALL_HEAD: case PLAYER_WALL_HEAD:

View File

@ -2,6 +2,7 @@ package io.github.thebusybiscuit.slimefun4.core.services;
import java.util.Optional; import java.util.Optional;
import org.bukkit.Keyed;
import org.bukkit.NamespacedKey; import org.bukkit.NamespacedKey;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
@ -20,7 +21,7 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
* @see SlimefunItemStack * @see SlimefunItemStack
* *
*/ */
public class CustomItemDataService implements PersistentDataService { public class CustomItemDataService implements PersistentDataService, Keyed {
private final NamespacedKey namespacedKey; private final NamespacedKey namespacedKey;
@ -28,6 +29,11 @@ public class CustomItemDataService implements PersistentDataService {
namespacedKey = new NamespacedKey(plugin, key); namespacedKey = new NamespacedKey(plugin, key);
} }
@Override
public NamespacedKey getKey() {
return namespacedKey;
}
public void setItemData(ItemStack item, String id) { public void setItemData(ItemStack item, String id) {
ItemMeta im = item.getItemMeta(); ItemMeta im = item.getItemMeta();
setItemData(im, id); setItemData(im, id);

View File

@ -26,7 +26,7 @@ public class CustomTextureService {
public CustomTextureService(Plugin plugin) { public CustomTextureService(Plugin plugin) {
config = new Config(plugin, "item-models.yml"); config = new Config(plugin, "item-models.yml");
config.getConfiguration().options().header("This file is used to assign items from Slimefun or any of its addons\n" + "the 'CustomModelData' NBT tag. This can be used in conjunction with a custom resource pack\n" + "to give items custom textures.\n\n" + "There is no official Slimefun resource pack at the moment."); config.getConfiguration().options().header("This file is used to assign items from Slimefun or any of its addons\n" + "the 'CustomModelData' NBT tag. This can be used in conjunction with a custom resource pack\n" + "to give items custom textures.\n0 means there is no data assigned to that item.\n\n" + "There is no official Slimefun resource pack at the moment.");
config.getConfiguration().options().copyHeader(true); config.getConfiguration().options().copyHeader(true);
} }

View File

@ -39,13 +39,16 @@ public class LocalizationService extends SlimefunLocalization implements Persist
private final Map<String, Language> languages = new LinkedHashMap<>(); private final Map<String, Language> languages = new LinkedHashMap<>();
private final boolean translationsEnabled; private final boolean translationsEnabled;
private final SlimefunPlugin plugin; private final SlimefunPlugin plugin;
private final String prefix;
private final NamespacedKey languageKey; private final NamespacedKey languageKey;
private final Language defaultLanguage; private final Language defaultLanguage;
public LocalizationService(SlimefunPlugin plugin, String serverDefaultLanguage) { public LocalizationService(SlimefunPlugin plugin, String prefix, String serverDefaultLanguage) {
super(plugin); super(plugin);
this.plugin = plugin; this.plugin = plugin;
this.prefix = prefix;
translationsEnabled = SlimefunPlugin.getCfg().getBoolean("options.enable-translations"); translationsEnabled = SlimefunPlugin.getCfg().getBoolean("options.enable-translations");
languageKey = new NamespacedKey(plugin, LANGUAGE_PATH); languageKey = new NamespacedKey(plugin, LANGUAGE_PATH);
defaultLanguage = new Language(serverDefaultLanguage, "11b3188fd44902f72602bd7c2141f5a70673a411adb3d81862c69e536166b"); defaultLanguage = new Language(serverDefaultLanguage, "11b3188fd44902f72602bd7c2141f5a70673a411adb3d81862c69e536166b");
@ -69,6 +72,20 @@ public class LocalizationService extends SlimefunLocalization implements Persist
save(); save();
} }
/**
* This method returns whether translations are enabled on this {@link Server}.
*
* @return Whether translations are enabled
*/
public boolean isEnabled() {
return translationsEnabled;
}
@Override
public String getPrefix() {
return prefix;
}
@Override @Override
public NamespacedKey getKey() { public NamespacedKey getKey() {
return languageKey; return languageKey;
@ -90,14 +107,14 @@ public class LocalizationService extends SlimefunLocalization implements Persist
return containsResource("messages_" + language) || containsResource("researches_" + language) || containsResource("resources_" + language) || containsResource("categories_" + language) || containsResource("recipes_" + language); return containsResource("messages_" + language) || containsResource("researches_" + language) || containsResource("resources_" + language) || containsResource("categories_" + language) || containsResource("recipes_" + language);
} }
private boolean containsResource(String file) {
return plugin.getClass().getResource("/languages/" + file + ".yml") != null;
}
public boolean isLanguageLoaded(String id) { public boolean isLanguageLoaded(String id) {
return languages.containsKey(id); return languages.containsKey(id);
} }
private boolean containsResource(String file) {
return plugin.getClass().getResource("/languages/" + file + ".yml") != null;
}
@Override @Override
public Language getDefaultLanguage() { public Language getDefaultLanguage() {
return defaultLanguage; return defaultLanguage;
@ -122,7 +139,6 @@ public class LocalizationService extends SlimefunLocalization implements Persist
// Clearing out the old Language (if necessary) // Clearing out the old Language (if necessary)
if (reset) { if (reset) {
getConfig().clear(); getConfig().clear();
setPrefix("&aSlimefun 4 &7> ");
} }
defaultLanguage.setResearches(streamConfigFile("researches_" + language + ".yml", null)); defaultLanguage.setResearches(streamConfigFile("researches_" + language + ".yml", null));
@ -167,6 +183,16 @@ public class LocalizationService extends SlimefunLocalization implements Persist
} }
} }
/**
* This returns the progress of translation for any given {@link Language}.
* The progress is determined by the amount of translated strings divided by the amount
* of strings in the english {@link Language} file and multiplied by 100.0
*
* @param lang
* The {@link Language} to get the progress of
*
* @return A percentage {@code (0.0 - 100.0)} for the progress of translation of that {@link Language}
*/
public double getProgress(Language lang) { public double getProgress(Language lang) {
int defaultKeys = getTotalKeys(languages.get("en")); int defaultKeys = getTotalKeys(languages.get("en"));
if (defaultKeys == 0) return 0; if (defaultKeys == 0) return 0;
@ -209,8 +235,4 @@ public class LocalizationService extends SlimefunLocalization implements Persist
return null; return null;
} }
} }
public boolean isEnabled() {
return translationsEnabled;
}
} }

View File

@ -54,6 +54,17 @@ public class MinecraftRecipeService {
return snapshot.getRecipeOutput(MinecraftRecipe.FURNACE, input); return snapshot.getRecipeOutput(MinecraftRecipe.FURNACE, input);
} }
/**
* This returns the shape of a given {@link Recipe}.
* For any shapeless {@link Recipe} the result will be equivalent to
* {@link RecipeSnapshot#getRecipeInput(Recipe)}.
* For a {@link ShapedRecipe} this method will fix the order so it matches a
* 3x3 crafting grid.
*
* @param recipe
* The {@link Recipe} to get the shape from
* @return An Array of {@link RecipeChoice} representing the shape of this {@link Recipe}
*/
public RecipeChoice[] getRecipeShape(Recipe recipe) { public RecipeChoice[] getRecipeShape(Recipe recipe) {
if (recipe instanceof ShapedRecipe) { if (recipe instanceof ShapedRecipe) {
List<RecipeChoice> choices = new LinkedList<>(); List<RecipeChoice> choices = new LinkedList<>();

View File

@ -13,6 +13,7 @@ import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.logging.Level; import java.util.logging.Level;
import org.bukkit.Server;
import org.bukkit.World; import org.bukkit.World;
import io.github.thebusybiscuit.cscorelib2.collections.OptionalMap; import io.github.thebusybiscuit.cscorelib2.collections.OptionalMap;
@ -116,6 +117,27 @@ public class PerWorldSettingsService {
return !items.contains(item.getID()); return !items.contains(item.getID());
} }
/**
* This method enables or disables the given {@link SlimefunItem} in the specified {@link World}.
*
* @param world
* The {@link World} in which to disable or enable the given {@link SlimefunItem}
* @param item
* The {@link SlimefunItem} to enable or disable
* @param enabled
* Whether the given {@link SlimefunItem} should be enabled in that world
*/
public void setEnabled(World world, SlimefunItem item, boolean enabled) {
Set<String> items = disabledItems.computeIfAbsent(world.getName(), this::loadWorld);
if (enabled) {
items.remove(item.getID());
}
else {
items.add(item.getID());
}
}
/** /**
* This checks whether the given {@link World} is enabled or not. * This checks whether the given {@link World} is enabled or not.
* *
@ -143,6 +165,29 @@ public class PerWorldSettingsService {
return isWorldEnabled(world) && disabledAddons.getOrDefault(addon, Collections.emptySet()).contains(world.getName()); return isWorldEnabled(world) && disabledAddons.getOrDefault(addon, Collections.emptySet()).contains(world.getName());
} }
/**
* This will forcefully save the settings for that {@link World}.
* This should only be called if you altered the settings while the {@link Server} was still running.
* This writes to a {@link File} so it can be a heavy operation.
*
* @param world
* The {@link World} to save
*/
public void save(World world) {
Set<String> items = disabledItems.computeIfAbsent(world.getName(), this::loadWorld);
Config config = new Config(plugin, "world-settings/" + world + ".yml");
for (SlimefunItem item : SlimefunPlugin.getRegistry().getEnabledSlimefunItems()) {
if (item != null && item.getID() != null) {
String addon = item.getAddon().getName().toLowerCase(Locale.ROOT);
config.setValue(addon + '.' + item.getID(), !items.contains(item.getID()));
}
}
config.save();
}
private Set<String> loadWorld(String name) { private Set<String> loadWorld(String name) {
Optional<Set<String>> optional = disabledItems.get(name); Optional<Set<String>> optional = disabledItems.get(name);

View File

@ -10,6 +10,13 @@ import org.bukkit.persistence.PersistentDataType;
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion; import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
import me.mrCookieSlime.Slimefun.SlimefunPlugin; import me.mrCookieSlime.Slimefun.SlimefunPlugin;
/**
* This interface is used to defer calls to Peristent Data and make sure they are only called
* if the {@link MinecraftVersion} supports it.
*
* @author TheBusyBiscuit
*
*/
interface PersistentDataService { interface PersistentDataService {
default void setString(Object obj, NamespacedKey key, String value) { default void setString(Object obj, NamespacedKey key, String value) {

View File

@ -8,6 +8,7 @@ import org.bukkit.plugin.Plugin;
import io.github.thebusybiscuit.cscorelib2.updater.GitHubBuildsUpdater; import io.github.thebusybiscuit.cscorelib2.updater.GitHubBuildsUpdater;
import io.github.thebusybiscuit.cscorelib2.updater.Updater; import io.github.thebusybiscuit.cscorelib2.updater.Updater;
import io.github.thebusybiscuit.slimefun4.api.SlimefunBranch; import io.github.thebusybiscuit.slimefun4.api.SlimefunBranch;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
/** /**
* This Class represents our {@link Updater} Service. * This Class represents our {@link Updater} Service.
@ -19,11 +20,20 @@ import io.github.thebusybiscuit.slimefun4.api.SlimefunBranch;
*/ */
public class UpdaterService { public class UpdaterService {
private final Plugin plugin; private final SlimefunPlugin plugin;
private final Updater updater; private final Updater updater;
private final SlimefunBranch branch; private final SlimefunBranch branch;
public UpdaterService(Plugin plugin, File file) { /**
* This will create a new {@link UpdaterService} for the given {@link SlimefunPlugin}.
* The {@link File} should be the result of the getFile() operation of that {@link Plugin}.
*
* @param plugin
* The instance of Slimefun
* @param file
* The {@link File} of this {@link Plugin}
*/
public UpdaterService(SlimefunPlugin plugin, File file) {
this.plugin = plugin; this.plugin = plugin;
String version = plugin.getDescription().getVersion(); String version = plugin.getDescription().getVersion();
@ -68,11 +78,11 @@ public class UpdaterService {
updater.start(); updater.start();
} }
else { else {
drawBorder(); printBorder();
plugin.getLogger().log(Level.WARNING, "It looks like you are using an unofficially modified build of Slimefun!"); plugin.getLogger().log(Level.WARNING, "It looks like you are using an unofficially modified build of Slimefun!");
plugin.getLogger().log(Level.WARNING, "Auto-Updates have been disabled, this build is not considered safe."); plugin.getLogger().log(Level.WARNING, "Auto-Updates have been disabled, this build is not considered safe.");
plugin.getLogger().log(Level.WARNING, "Do not report bugs encountered in this Version of Slimefun to any official sources."); plugin.getLogger().log(Level.WARNING, "Do not report bugs encountered in this Version of Slimefun to any official sources.");
drawBorder(); printBorder();
} }
} }
@ -80,7 +90,7 @@ public class UpdaterService {
* This method is called when the {@link UpdaterService} was disabled. * This method is called when the {@link UpdaterService} was disabled.
*/ */
public void disable() { public void disable() {
drawBorder(); printBorder();
plugin.getLogger().log(Level.WARNING, "It looks like you have disabled auto-updates for Slimefun!"); plugin.getLogger().log(Level.WARNING, "It looks like you have disabled auto-updates for Slimefun!");
plugin.getLogger().log(Level.WARNING, "Auto-Updates keep your server safe, performant and bug-free."); plugin.getLogger().log(Level.WARNING, "Auto-Updates keep your server safe, performant and bug-free.");
plugin.getLogger().log(Level.WARNING, "We respect your decision."); plugin.getLogger().log(Level.WARNING, "We respect your decision.");
@ -89,10 +99,10 @@ public class UpdaterService {
plugin.getLogger().log(Level.WARNING, "If you are just scared of Slimefun breaking, then please consider using a \"stable\" build instead of disabling auto-updates."); plugin.getLogger().log(Level.WARNING, "If you are just scared of Slimefun breaking, then please consider using a \"stable\" build instead of disabling auto-updates.");
} }
drawBorder(); printBorder();
} }
private void drawBorder() { private void printBorder() {
plugin.getLogger().log(Level.WARNING, "#######################################################"); plugin.getLogger().log(Level.WARNING, "#######################################################");
} }

View File

@ -16,7 +16,7 @@ import me.mrCookieSlime.Slimefun.api.Slimefun;
/** /**
* This Service holds all interactions and hooks with third-party {@link Plugin Plugins} * This Service holds all interactions and hooks with third-party {@link Plugin Plugins}
* that are not a dependency or a {@link SlimefunAddon}. * that are not necessarily a dependency or a {@link SlimefunAddon}.
* *
* Integration with these plugins happens inside Slimefun itself. * Integration with these plugins happens inside Slimefun itself.
* *

View File

@ -1,12 +1,25 @@
package io.github.thebusybiscuit.slimefun4.implementation.items.food; package io.github.thebusybiscuit.slimefun4.implementation.items.food;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.slimefun4.implementation.items.tools.SlimefunBackpack; import io.github.thebusybiscuit.slimefun4.implementation.items.tools.SlimefunBackpack;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.CoolerListener;
import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
/**
* The {@link Cooler} is a special variant of the {@link SlimefunBackpack}.
* It can only hold {@link Juice Juices} and auto-consumes those when a {@link Player}
* loses hunger while carrying a {@link Cooler} filled with {@link Juice}.
*
* @author TheBusyBiscuit
*
* @see Juice
* @see CoolerListener
*
*/
public class Cooler extends SlimefunBackpack { public class Cooler extends SlimefunBackpack {
public Cooler(int size, Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { public Cooler(int size, Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {

View File

@ -0,0 +1,42 @@
package io.github.thebusybiscuit.slimefun4.implementation.items.weapons;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.VampireBladeListener;
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
/**
* The {@link VampireBlade} is a weapon that applies a Healing effect to any {@link Player}
* who damages another {@link LivingEntity} with this sword.
*
* @author TheBusyBiscuit
*
* @see VampireBladeListener
*
*/
public class VampireBlade extends SlimefunItem {
private final ItemSetting<Integer> chance = new ItemSetting<>("chance", 45);
public VampireBlade(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(category, item, recipeType, recipe);
addItemSetting(chance);
}
/**
* This method returns the chance of a {@link VampireBlade} to apply its healing effect.
*
* @return The chance for a healing effect
*/
public int getChance() {
return chance.getValue();
}
}

View File

@ -51,14 +51,17 @@ import me.mrCookieSlime.Slimefun.api.Slimefun;
*/ */
public class AncientAltarListener implements Listener { public class AncientAltarListener implements Listener {
private AncientAltar altar;
private final Set<AltarRecipe> altarRecipes = new HashSet<>(); private final Set<AltarRecipe> altarRecipes = new HashSet<>();
private final Set<Location> altarsInUse = new HashSet<>(); private final Set<Location> altarsInUse = new HashSet<>();
private final List<Block> altars = new ArrayList<>(); private final List<Block> altars = new ArrayList<>();
private final Set<UUID> removedItems = new HashSet<>(); private final Set<UUID> removedItems = new HashSet<>();
public void register(SlimefunPlugin plugin) { public void register(SlimefunPlugin plugin, AncientAltar altar) {
plugin.getServer().getPluginManager().registerEvents(this, plugin); plugin.getServer().getPluginManager().registerEvents(this, plugin);
this.altar = altar;
} }
public Set<Location> getAltarsInUse() { public Set<Location> getAltarsInUse() {
@ -75,7 +78,9 @@ public class AncientAltarListener implements Listener {
@EventHandler @EventHandler
public void onInteract(PlayerRightClickEvent e) { public void onInteract(PlayerRightClickEvent e) {
if (e.useBlock() == Result.DENY) return; if (altar == null || altar.isDisabled() || e.useBlock() == Result.DENY) {
return;
}
Optional<Block> blockOptional = e.getClickedBlock(); Optional<Block> blockOptional = e.getClickedBlock();
if (!blockOptional.isPresent()) return; if (!blockOptional.isPresent()) return;
@ -208,6 +213,10 @@ public class AncientAltarListener implements Listener {
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onBlockPlace(BlockPlaceEvent e) { public void onBlockPlace(BlockPlaceEvent e) {
if (altar == null || altar.isDisabled()) {
return;
}
Block pedestal = e.getBlockPlaced().getRelative(BlockFace.DOWN); Block pedestal = e.getBlockPlaced().getRelative(BlockFace.DOWN);
if (pedestal.getType() == Material.DISPENSER) { if (pedestal.getType() == Material.DISPENSER) {

View File

@ -15,9 +15,8 @@ import io.github.thebusybiscuit.slimefun4.api.player.PlayerBackpack;
import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile; import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile;
import io.github.thebusybiscuit.slimefun4.implementation.items.food.Cooler; import io.github.thebusybiscuit.slimefun4.implementation.items.food.Cooler;
import io.github.thebusybiscuit.slimefun4.implementation.items.food.Juice; import io.github.thebusybiscuit.slimefun4.implementation.items.food.Juice;
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
import me.mrCookieSlime.Slimefun.SlimefunPlugin; import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.Lists.SlimefunItems; import me.mrCookieSlime.Slimefun.api.Slimefun;
/** /**
* This {@link Listener} listens for a {@link FoodLevelChangeEvent} and consumes a {@link Juice} * This {@link Listener} listens for a {@link FoodLevelChangeEvent} and consumes a {@link Juice}
@ -31,21 +30,34 @@ import me.mrCookieSlime.Slimefun.Lists.SlimefunItems;
*/ */
public class CoolerListener implements Listener { public class CoolerListener implements Listener {
public CoolerListener(SlimefunPlugin plugin) { private final Cooler cooler;
public CoolerListener(SlimefunPlugin plugin, Cooler cooler) {
plugin.getServer().getPluginManager().registerEvents(this, plugin); plugin.getServer().getPluginManager().registerEvents(this, plugin);
this.cooler = cooler;
} }
@EventHandler @EventHandler
public void onStarve(FoodLevelChangeEvent e) { public void onStarve(FoodLevelChangeEvent e) {
if (cooler.isDisabled()) {
return;
}
if (e.getFoodLevel() < ((Player) e.getEntity()).getFoodLevel()) { if (e.getFoodLevel() < ((Player) e.getEntity()).getFoodLevel()) {
Player p = (Player) e.getEntity(); Player p = (Player) e.getEntity();
for (ItemStack item : p.getInventory().getContents()) { for (ItemStack item : p.getInventory().getContents()) {
if (SlimefunUtils.isItemSimilar(item, SlimefunItems.COOLER, false)) { if (cooler.isItem(item)) {
PlayerBackpack backpack = PlayerProfile.getBackpack(item); if (Slimefun.hasUnlocked(p, cooler, true)) {
PlayerBackpack backpack = PlayerProfile.getBackpack(item);
if (backpack != null && consumeJuice(p, backpack)) { if (backpack != null && consumeJuice(p, backpack)) {
break; break;
}
}
else {
return;
} }
} }
} }

View File

@ -18,6 +18,19 @@ import me.mrCookieSlime.Slimefun.Lists.SlimefunItems;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.api.Slimefun; import me.mrCookieSlime.Slimefun.api.Slimefun;
/**
* This {@link Listener} is responsible for listening to the {@link PlayerToggleSneakEvent}
* to start tasks for various gadgets that are activated by pressing shift,
* like the {@link Jetpack} or {@link JetBoots}
*
* @author TheBusyBiscuit
*
* @see JetpackTask
* @see JetBootsTask
* @see ParachuteTask
* @see MagnetTask
*
*/
public class GadgetsListener implements Listener { public class GadgetsListener implements Listener {
public GadgetsListener(SlimefunPlugin plugin) { public GadgetsListener(SlimefunPlugin plugin) {

View File

@ -20,22 +20,31 @@ import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.event.entity.ProjectileHitEvent; import org.bukkit.event.entity.ProjectileHitEvent;
import org.bukkit.util.Vector; import org.bukkit.util.Vector;
import io.github.thebusybiscuit.slimefun4.implementation.items.tools.GrapplingHook;
import me.mrCookieSlime.Slimefun.SlimefunPlugin; import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.Lists.SlimefunItems; import me.mrCookieSlime.Slimefun.Lists.SlimefunItems;
import me.mrCookieSlime.Slimefun.api.Slimefun; import me.mrCookieSlime.Slimefun.api.Slimefun;
public class GrapplingHookListener implements Listener { public class GrapplingHookListener implements Listener {
private GrapplingHook grapplingHook;
private final Map<UUID, Boolean> jumpState = new HashMap<>(); private final Map<UUID, Boolean> jumpState = new HashMap<>();
private final Set<UUID> invulnerable = new HashSet<>(); private final Set<UUID> invulnerable = new HashSet<>();
private final Map<UUID, Entity[]> temporaryEntities = new HashMap<>(); private final Map<UUID, Entity[]> temporaryEntities = new HashMap<>();
public void register(SlimefunPlugin plugin) { public void register(SlimefunPlugin plugin, GrapplingHook grapplingHook) {
plugin.getServer().getPluginManager().registerEvents(this, plugin); plugin.getServer().getPluginManager().registerEvents(this, plugin);
this.grapplingHook = grapplingHook;
} }
@EventHandler @EventHandler
public void onArrowHitEntity(EntityDamageByEntityEvent e) { public void onArrowHitEntity(EntityDamageByEntityEvent e) {
if (grapplingHook == null || grapplingHook.isDisabled()) {
return;
}
if (e.getDamager() instanceof Arrow) { if (e.getDamager() instanceof Arrow) {
handleGrapplingHook((Arrow) e.getDamager()); handleGrapplingHook((Arrow) e.getDamager());
} }
@ -43,6 +52,10 @@ public class GrapplingHookListener implements Listener {
@EventHandler @EventHandler
public void onArrowHit(ProjectileHitEvent e) { public void onArrowHit(ProjectileHitEvent e) {
if (grapplingHook == null || grapplingHook.isDisabled()) {
return;
}
Slimefun.runSync(() -> { Slimefun.runSync(() -> {
if (e.getEntity().isValid() && e.getEntity() instanceof Arrow) { if (e.getEntity().isValid() && e.getEntity() instanceof Arrow) {
handleGrapplingHook((Arrow) e.getEntity()); handleGrapplingHook((Arrow) e.getEntity());
@ -52,6 +65,10 @@ public class GrapplingHookListener implements Listener {
@EventHandler @EventHandler
public void onArrowHit(EntityDamageEvent e) { public void onArrowHit(EntityDamageEvent e) {
if (grapplingHook == null || grapplingHook.isDisabled()) {
return;
}
if (e.getEntity() instanceof Player && e.getCause() == DamageCause.FALL && invulnerable.contains(e.getEntity().getUniqueId())) { if (e.getEntity() instanceof Player && e.getCause() == DamageCause.FALL && invulnerable.contains(e.getEntity().getUniqueId())) {
e.setCancelled(true); e.setCancelled(true);
invulnerable.remove(e.getEntity().getUniqueId()); invulnerable.remove(e.getEntity().getUniqueId());

View File

@ -47,7 +47,7 @@ public class MultiBlockListener implements Listener {
for (MultiBlock mb : SlimefunPlugin.getRegistry().getMultiBlocks()) { for (MultiBlock mb : SlimefunPlugin.getRegistry().getMultiBlocks()) {
Block center = b.getRelative(mb.getTriggerBlock()); Block center = b.getRelative(mb.getTriggerBlock());
if (compareMaterials(center, mb.getBuild(), mb.isSymmetric())) { if (compareMaterials(center, mb.getStructure(), mb.isSymmetric())) {
multiblocks.add(mb); multiblocks.add(mb);
} }
} }

View File

@ -20,12 +20,19 @@ import me.mrCookieSlime.Slimefun.SlimefunPlugin;
*/ */
public class SeismicAxeListener implements Listener { public class SeismicAxeListener implements Listener {
public SeismicAxeListener(SlimefunPlugin plugin) { private final SeismicAxe seismicAxe;
public SeismicAxeListener(SlimefunPlugin plugin, SeismicAxe seismicAxe) {
plugin.getServer().getPluginManager().registerEvents(this, plugin); plugin.getServer().getPluginManager().registerEvents(this, plugin);
this.seismicAxe = seismicAxe;
} }
@EventHandler @EventHandler
public void onBlockFall(EntityChangeBlockEvent e) { public void onBlockFall(EntityChangeBlockEvent e) {
if (seismicAxe.isDisabled()) {
return;
}
if (e.getEntity().getType() == EntityType.FALLING_BLOCK && e.getEntity().hasMetadata("seismic_axe")) { if (e.getEntity().getType() == EntityType.FALLING_BLOCK && e.getEntity().hasMetadata("seismic_axe")) {
e.setCancelled(true); e.setCancelled(true);
e.getEntity().remove(); e.getEntity().remove();

View File

@ -11,24 +11,46 @@ import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType; import org.bukkit.potion.PotionEffectType;
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils; import io.github.thebusybiscuit.slimefun4.implementation.items.weapons.VampireBlade;
import me.mrCookieSlime.Slimefun.SlimefunPlugin; import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.Lists.SlimefunItems; import me.mrCookieSlime.Slimefun.api.Slimefun;
/**
* This {@link Listener} is exclusively used for the {@link VampireBlade}.
* It handles the {@link PotionEffect}
*
* @author TheBusyBiscuit
*
* @see VampireBlade
*
*/
public class VampireBladeListener implements Listener { public class VampireBladeListener implements Listener {
public VampireBladeListener(SlimefunPlugin plugin) { private final VampireBlade blade;
public VampireBladeListener(SlimefunPlugin plugin, VampireBlade blade) {
plugin.getServer().getPluginManager().registerEvents(this, plugin); plugin.getServer().getPluginManager().registerEvents(this, plugin);
this.blade = blade;
} }
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onDamage(EntityDamageByEntityEvent e) { public void onDamage(EntityDamageByEntityEvent e) {
if (e.getDamager() instanceof Player && ThreadLocalRandom.current().nextInt(100) < 45) { if (blade.isDisabled()) {
return;
}
if (e.getDamager() instanceof Player && ThreadLocalRandom.current().nextInt(100) < blade.getChance()) {
Player p = (Player) e.getDamager(); Player p = (Player) e.getDamager();
if (SlimefunUtils.isItemSimilar(p.getInventory().getItemInMainHand(), SlimefunItems.BLADE_OF_VAMPIRES, true)) { if (blade.isItem(p.getInventory().getItemInMainHand())) {
p.playSound(p.getLocation(), Sound.ENTITY_ARROW_HIT_PLAYER, 0.7F, 0.7F); if (Slimefun.hasUnlocked(p, blade, true)) {
p.addPotionEffect(new PotionEffect(PotionEffectType.HEAL, 1, 1)); p.playSound(p.getLocation(), Sound.ENTITY_ARROW_HIT_PLAYER, 0.7F, 0.7F);
p.addPotionEffect(new PotionEffect(PotionEffectType.HEAL, 1, 1));
}
else {
e.setCancelled(true);
}
} }
} }
} }

View File

@ -8,7 +8,6 @@ import org.bukkit.event.inventory.CraftItemEvent;
import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryType; import org.bukkit.event.inventory.InventoryType;
import org.bukkit.event.inventory.PrepareItemCraftEvent; import org.bukkit.event.inventory.PrepareItemCraftEvent;
import org.bukkit.inventory.BrewerInventory;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
@ -19,6 +18,16 @@ import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.Lists.SlimefunItems; import me.mrCookieSlime.Slimefun.Lists.SlimefunItems;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
/**
* This {@link Listener} prevents any {@link SlimefunItem} from being used in a vanilla
* machine like the workbench, grindstone, brewing stand or an anvil.
*
* @author TheBusyBiscuit
* @author NathanAdhitya
* @author Steve
* @author VoidAngel
*
*/
public class VanillaMachinesListener implements Listener { public class VanillaMachinesListener implements Listener {
public VanillaMachinesListener(SlimefunPlugin plugin) { public VanillaMachinesListener(SlimefunPlugin plugin) {
@ -71,7 +80,7 @@ public class VanillaMachinesListener implements Listener {
@EventHandler @EventHandler
public void onAnvil(InventoryClickEvent e) { public void onAnvil(InventoryClickEvent e) {
if (e.getRawSlot() == 2 && e.getWhoClicked() instanceof Player && e.getInventory().getType() == InventoryType.ANVIL) { if (e.getRawSlot() == 2 && e.getInventory().getType() == InventoryType.ANVIL && e.getWhoClicked() instanceof Player) {
ItemStack item1 = e.getInventory().getContents()[0]; ItemStack item1 = e.getInventory().getContents()[0];
ItemStack item2 = e.getInventory().getContents()[1]; ItemStack item2 = e.getInventory().getContents()[1];
@ -86,7 +95,7 @@ public class VanillaMachinesListener implements Listener {
public void onPreBrew(InventoryClickEvent e) { public void onPreBrew(InventoryClickEvent e) {
Inventory inventory = e.getInventory(); Inventory inventory = e.getInventory();
if (inventory instanceof BrewerInventory && inventory.getHolder() instanceof BrewingStand && e.getRawSlot() < inventory.getSize()) { if (inventory.getType() == InventoryType.BREWING && e.getRawSlot() < inventory.getSize() && inventory.getHolder() instanceof BrewingStand) {
e.setCancelled(SlimefunItem.getByItem(e.getCursor()) != null); e.setCancelled(SlimefunItem.getByItem(e.getCursor()) != null);
} }
} }

View File

@ -29,6 +29,7 @@ import io.github.thebusybiscuit.slimefun4.core.attributes.Radioactivity;
import io.github.thebusybiscuit.slimefun4.implementation.items.EasterEgg; import io.github.thebusybiscuit.slimefun4.implementation.items.EasterEgg;
import io.github.thebusybiscuit.slimefun4.implementation.items.RadioactiveItem; import io.github.thebusybiscuit.slimefun4.implementation.items.RadioactiveItem;
import io.github.thebusybiscuit.slimefun4.implementation.items.VanillaItem; import io.github.thebusybiscuit.slimefun4.implementation.items.VanillaItem;
import io.github.thebusybiscuit.slimefun4.implementation.items.altar.AncientAltar;
import io.github.thebusybiscuit.slimefun4.implementation.items.altar.AncientPedestal; import io.github.thebusybiscuit.slimefun4.implementation.items.altar.AncientPedestal;
import io.github.thebusybiscuit.slimefun4.implementation.items.androids.AdvancedFarmerAndroid; import io.github.thebusybiscuit.slimefun4.implementation.items.androids.AdvancedFarmerAndroid;
import io.github.thebusybiscuit.slimefun4.implementation.items.androids.AndroidType; import io.github.thebusybiscuit.slimefun4.implementation.items.androids.AndroidType;
@ -168,6 +169,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.items.weapons.Explosive
import io.github.thebusybiscuit.slimefun4.implementation.items.weapons.IcyBow; import io.github.thebusybiscuit.slimefun4.implementation.items.weapons.IcyBow;
import io.github.thebusybiscuit.slimefun4.implementation.items.weapons.SeismicAxe; import io.github.thebusybiscuit.slimefun4.implementation.items.weapons.SeismicAxe;
import io.github.thebusybiscuit.slimefun4.implementation.items.weapons.SwordOfBeheading; import io.github.thebusybiscuit.slimefun4.implementation.items.weapons.SwordOfBeheading;
import io.github.thebusybiscuit.slimefun4.implementation.items.weapons.VampireBlade;
import me.mrCookieSlime.CSCoreLibPlugin.CSCoreLib; import me.mrCookieSlime.CSCoreLibPlugin.CSCoreLib;
import me.mrCookieSlime.Slimefun.SlimefunPlugin; import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.Lists.Categories; import me.mrCookieSlime.Slimefun.Lists.Categories;
@ -997,7 +999,7 @@ public final class SlimefunItemSetup {
new PotionEffect[] {new PotionEffect(PotionEffectType.JUMP, 300, 5)}) new PotionEffect[] {new PotionEffect(PotionEffectType.JUMP, 300, 5)})
.register(plugin); .register(plugin);
new SlimefunItem(Categories.WEAPONS, (SlimefunItemStack) SlimefunItems.BLADE_OF_VAMPIRES, RecipeType.MAGIC_WORKBENCH, new VampireBlade(Categories.WEAPONS, (SlimefunItemStack) SlimefunItems.BLADE_OF_VAMPIRES, RecipeType.MAGIC_WORKBENCH,
new ItemStack[] {null, new ItemStack(Material.WITHER_SKELETON_SKULL), null, null, new ItemStack(Material.WITHER_SKELETON_SKULL), null, null, new ItemStack(Material.BLAZE_ROD), null}) new ItemStack[] {null, new ItemStack(Material.WITHER_SKELETON_SKULL), null, null, new ItemStack(Material.WITHER_SKELETON_SKULL), null, null, new ItemStack(Material.BLAZE_ROD), null})
.register(plugin); .register(plugin);
@ -1557,7 +1559,7 @@ public final class SlimefunItemSetup {
new CustomItem(SlimefunItems.ANCIENT_PEDESTAL, 4)) new CustomItem(SlimefunItems.ANCIENT_PEDESTAL, 4))
.register(plugin); .register(plugin);
new SlimefunItem(Categories.MAGIC, SlimefunItems.ANCIENT_ALTAR, RecipeType.MAGIC_WORKBENCH, new AncientAltar(Categories.MAGIC, SlimefunItems.ANCIENT_ALTAR, RecipeType.MAGIC_WORKBENCH,
new ItemStack[] {null, new ItemStack(Material.ENCHANTING_TABLE), null, SlimefunItems.MAGIC_LUMP_3, SlimefunItems.GOLD_8K, SlimefunItems.MAGIC_LUMP_3, new ItemStack(Material.OBSIDIAN), SlimefunItems.GOLD_8K, new ItemStack(Material.OBSIDIAN)}) new ItemStack[] {null, new ItemStack(Material.ENCHANTING_TABLE), null, SlimefunItems.MAGIC_LUMP_3, SlimefunItems.GOLD_8K, SlimefunItems.MAGIC_LUMP_3, new ItemStack(Material.OBSIDIAN), SlimefunItems.GOLD_8K, new ItemStack(Material.OBSIDIAN)})
.register(plugin); .register(plugin);

View File

@ -4,11 +4,8 @@ import org.bukkit.Bukkit;
import org.bukkit.World; import org.bukkit.World;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.ButcherAndroidListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.ButcherAndroidListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.CoolerListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.NetworkListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.NetworkListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.SeismicAxeListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.TeleporterListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.TeleporterListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.VampireBladeListener;
import io.github.thebusybiscuit.slimefun4.implementation.setup.PostSetup; import io.github.thebusybiscuit.slimefun4.implementation.setup.PostSetup;
import me.mrCookieSlime.Slimefun.SlimefunPlugin; import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
@ -55,26 +52,6 @@ public class SlimefunStartupTask implements Runnable {
// Load all listeners that depend on items to be enabled // Load all listeners that depend on items to be enabled
if (isEnabled("ANCIENT_ALTAR")) {
SlimefunPlugin.getAncientAltarListener().register(plugin);
}
if (isEnabled("GRAPPLING_HOOK")) {
SlimefunPlugin.getGrapplingHookListener().register(plugin);
}
if (isEnabled("BLADE_OF_VAMPIRES")) {
new VampireBladeListener(plugin);
}
if (isEnabled("COOLER")) {
new CoolerListener(plugin);
}
if (isEnabled("SEISMIC_AXE")) {
new SeismicAxeListener(plugin);
}
if (isEnabled("ELEVATOR_PLATE", "GPS_ACTIVATION_DEVICE_SHARED", "GPS_ACTIVATION_DEVICE_PERSONAL")) { if (isEnabled("ELEVATOR_PLATE", "GPS_ACTIVATION_DEVICE_SHARED", "GPS_ACTIVATION_DEVICE_PERSONAL")) {
new TeleporterListener(plugin); new TeleporterListener(plugin);
} }

View File

@ -72,7 +72,7 @@ public final class SlimefunItems {
public static final ItemStack GILDED_BACKPACK = new SlimefunItemStack("GILDED_BACKPACK", "40cb1e67b512ab2d4bf3d7ace0eaaf61c32cd4681ddc3987ceb326706a33fa", "&eGilded Backpack", "", "&7Size: &e45", "&7ID: <ID>", "", "&7&eRight Click&7 to open"); public static final ItemStack GILDED_BACKPACK = new SlimefunItemStack("GILDED_BACKPACK", "40cb1e67b512ab2d4bf3d7ace0eaaf61c32cd4681ddc3987ceb326706a33fa", "&eGilded Backpack", "", "&7Size: &e45", "&7ID: <ID>", "", "&7&eRight Click&7 to open");
public static final ItemStack RADIANT_BACKPACK = new SlimefunItemStack("RADIANT_BACKPACK", "40cb1e67b512ab2d4bf3d7ace0eaaf61c32cd4681ddc3987ceb326706a33fa", "&eRadiant Backpack", "", "&7Size: &e54 (Double chest)", "&7ID: <ID>", "", "&7&eRight Click&7 to open"); public static final ItemStack RADIANT_BACKPACK = new SlimefunItemStack("RADIANT_BACKPACK", "40cb1e67b512ab2d4bf3d7ace0eaaf61c32cd4681ddc3987ceb326706a33fa", "&eRadiant Backpack", "", "&7Size: &e54 (Double chest)", "&7ID: <ID>", "", "&7&eRight Click&7 to open");
public static final SlimefunItemStack BOUND_BACKPACK = new SlimefunItemStack("BOUND_BACKPACK", "2a3b34862b9afb63cf8d5779966d3fba70af82b04e83f3eaf6449aeba", "&cSoulbound Backpack", "", "&7Size: &e36", "&7ID: <ID>", "", "&7&eRight Click&7 to open"); public static final SlimefunItemStack BOUND_BACKPACK = new SlimefunItemStack("BOUND_BACKPACK", "2a3b34862b9afb63cf8d5779966d3fba70af82b04e83f3eaf6449aeba", "&cSoulbound Backpack", "", "&7Size: &e36", "&7ID: <ID>", "", "&7&eRight Click&7 to open");
public static final ItemStack COOLER = new SlimefunItemStack("COOLER", "d4c1572584eb5de229de9f5a4f779d0aacbaffd33bcb33eb4536a6a2bc6a1", "&bCooler", "&rAllows you to store Juices/Smoothies", "&rand automatically consumes them when you are hungry", "&rand you have this in your Inventory", "", "&7Size: &e27", "&7ID: <ID>", "", "&7&eRight Click&7 to open"); public static final SlimefunItemStack COOLER = new SlimefunItemStack("COOLER", "d4c1572584eb5de229de9f5a4f779d0aacbaffd33bcb33eb4536a6a2bc6a1", "&bCooler", "&rAllows you to store Juices/Smoothies", "&rand automatically consumes them when you are hungry", "&rand you have this in your Inventory", "", "&7Size: &e27", "&7ID: <ID>", "", "&7&eRight Click&7 to open");
/* Jetpacks */ /* Jetpacks */
public static final SlimefunItemStack DURALUMIN_JETPACK = new SlimefunItemStack("DURALUMIN_JETPACK", Material.LEATHER_CHESTPLATE, Color.SILVER, "&9Electric Jetpack &7- &eI", "", "&8\u21E8 &7Material: &bDuralumin", "&c&o&8\u21E8 &e\u26A1 &70 / 20 J", "&8\u21E8 &7Thrust: &c0.35", "", "&7Hold &eShift&7 to use"); public static final SlimefunItemStack DURALUMIN_JETPACK = new SlimefunItemStack("DURALUMIN_JETPACK", Material.LEATHER_CHESTPLATE, Color.SILVER, "&9Electric Jetpack &7- &eI", "", "&8\u21E8 &7Material: &bDuralumin", "&c&o&8\u21E8 &e\u26A1 &70 / 20 J", "&8\u21E8 &7Thrust: &c0.35", "", "&7Hold &eShift&7 to use");
@ -178,8 +178,8 @@ public final class SlimefunItems {
public static final ItemStack GRANDMAS_WALKING_STICK = new SlimefunItemStack("GRANDMAS_WALKING_STICK", Material.STICK, "&7Grandmas Walking Stick"); public static final ItemStack GRANDMAS_WALKING_STICK = new SlimefunItemStack("GRANDMAS_WALKING_STICK", Material.STICK, "&7Grandmas Walking Stick");
public static final ItemStack GRANDPAS_WALKING_STICK = new SlimefunItemStack("GRANDPAS_WALKING_STICK", Material.STICK, "&7Grandpas Walking Stick"); public static final ItemStack GRANDPAS_WALKING_STICK = new SlimefunItemStack("GRANDPAS_WALKING_STICK", Material.STICK, "&7Grandpas Walking Stick");
public static final ItemStack SWORD_OF_BEHEADING = new SlimefunItemStack("SWORD_OF_BEHEADING", Material.IRON_SWORD, "&6Sword of Beheading", "&7Beheading II", "", "&rHas a chance to behead Mobs", "&r(even a higher chance for Wither Skeletons)"); public static final ItemStack SWORD_OF_BEHEADING = new SlimefunItemStack("SWORD_OF_BEHEADING", Material.IRON_SWORD, "&6Sword of Beheading", "&7Beheading II", "", "&rHas a chance to behead Mobs", "&r(even a higher chance for Wither Skeletons)");
public static final ItemStack BLADE_OF_VAMPIRES = new SlimefunItemStack("BLADE_OF_VAMPIRES", Material.GOLDEN_SWORD, "&cBlade of Vampires", "&7Life Steal I", "", "&rEverytime you attack something", "&ryou have a 45% chance to", "&rrecover 2 Hearts of your Health"); public static final SlimefunItemStack BLADE_OF_VAMPIRES = new SlimefunItemStack("BLADE_OF_VAMPIRES", Material.GOLDEN_SWORD, "&cBlade of Vampires", "&7Life Steal I", "", "&rEverytime you attack something", "&ryou have a 45% chance to", "&rrecover 2 Hearts of your Health");
public static final ItemStack SEISMIC_AXE = new SlimefunItemStack("SEISMIC_AXE", Material.IRON_AXE, "&aSeismic Axe", "", "&7&oA portable Earthquake...", "", "&7&eRight Click&7 to use"); public static final SlimefunItemStack SEISMIC_AXE = new SlimefunItemStack("SEISMIC_AXE", Material.IRON_AXE, "&aSeismic Axe", "", "&7&oA portable Earthquake...", "", "&7&eRight Click&7 to use");
static { static {
GRANDMAS_WALKING_STICK.addUnsafeEnchantment(Enchantment.KNOCKBACK, 2); GRANDMAS_WALKING_STICK.addUnsafeEnchantment(Enchantment.KNOCKBACK, 2);
@ -465,7 +465,7 @@ public final class SlimefunItems {
public static final ItemStack LEAD_DUST = new SlimefunItemStack("LEAD_DUST", Material.GUNPOWDER, "&6Lead Dust"); public static final ItemStack LEAD_DUST = new SlimefunItemStack("LEAD_DUST", Material.GUNPOWDER, "&6Lead Dust");
public static final ItemStack ZINC_DUST = new SlimefunItemStack("ZINC_DUST", Material.SUGAR, "&6Zinc Dust"); public static final ItemStack ZINC_DUST = new SlimefunItemStack("ZINC_DUST", Material.SUGAR, "&6Zinc Dust");
public static final ItemStack MAGNESIUM_DUST = new SlimefunItemStack("MAGNESIUM_DUST", Material.SUGAR, "&6Magnesium"); public static final ItemStack MAGNESIUM_DUST = new SlimefunItemStack("MAGNESIUM_DUST", Material.SUGAR, "&6Magnesium");
public static final ItemStack SULFATE = new SlimefunItemStack("SULFATE", Material.GLOWSTONE_DUST, "&6Sulfate"); public static final ItemStack SULFATE = new SlimefunItemStack("SULFATE", Material.GLOWSTONE_DUST, "&6Sulfate");
public static final ItemStack SILICON = new SlimefunItemStack("SILICON", Material.FIREWORK_STAR, "&6Silicon"); public static final ItemStack SILICON = new SlimefunItemStack("SILICON", Material.FIREWORK_STAR, "&6Silicon");
public static final ItemStack GOLD_24K_BLOCK = new SlimefunItemStack("GOLD_24K_BLOCK", Material.GOLD_BLOCK, "&rGold Block &7(24-Carat)"); public static final ItemStack GOLD_24K_BLOCK = new SlimefunItemStack("GOLD_24K_BLOCK", Material.GOLD_BLOCK, "&rGold Block &7(24-Carat)");
@ -785,7 +785,7 @@ public final class SlimefunItems {
static { static {
INFUSED_ELYTRA.addUnsafeEnchantment(Enchantment.MENDING, 1); INFUSED_ELYTRA.addUnsafeEnchantment(Enchantment.MENDING, 1);
if (SlimefunPlugin.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_14)) { if (SlimefunPlugin.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_14)) {
TABLE_SAW = new SlimefunItemStack("TABLE_SAW", Material.STONECUTTER, "&6Table Saw", "", "&aAllows you to get 8 planks from 1 Log", "&a(Works with all log types)"); TABLE_SAW = new SlimefunItemStack("TABLE_SAW", Material.STONECUTTER, "&6Table Saw", "", "&aAllows you to get 8 planks from 1 Log", "&a(Works with all log types)");
MAKESHIFT_SMELTERY = new SlimefunItemStack("MAKESHIFT_SMELTERY", Material.BLAST_FURNACE, "&eMakeshift Smeltery", "", "&rImprovised version of the Smeltery", "&rthat only allows you to", "&rsmelt dusts into ingots"); MAKESHIFT_SMELTERY = new SlimefunItemStack("MAKESHIFT_SMELTERY", Material.BLAST_FURNACE, "&eMakeshift Smeltery", "", "&rImprovised version of the Smeltery", "&rthat only allows you to", "&rsmelt dusts into ingots");

View File

@ -253,15 +253,23 @@ public class SlimefunItem implements Placeable {
return hidden; return hidden;
} }
/**
* This method will forcefully hide this {@link SlimefunItem} from the {@link SlimefunGuide}.
*
* @param hidden
* Whether to hide this {@link SlimefunItem} or not
*/
public void setHidden(boolean hidden) { public void setHidden(boolean hidden) {
this.hidden = hidden; if (this.hidden != hidden) {
this.hidden = hidden;
if (state == ItemState.ENABLED) { if (state == ItemState.ENABLED) {
if (hidden) { if (hidden) {
category.remove(this); category.remove(this);
} }
else { else {
category.add(this); category.add(this);
}
} }
} }
} }
@ -504,6 +512,7 @@ public class SlimefunItem implements Placeable {
*/ */
public SlimefunItem setUseableInWorkbench(boolean useable) { public SlimefunItem setUseableInWorkbench(boolean useable) {
this.useableInWorkbench = useable; this.useableInWorkbench = useable;
return this; return this;
} }

View File

@ -5,11 +5,11 @@ import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import org.bukkit.ChatColor;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import io.github.thebusybiscuit.cscorelib2.chat.ChatColors;
import io.github.thebusybiscuit.cscorelib2.math.DoubleHandler; import io.github.thebusybiscuit.cscorelib2.math.DoubleHandler;
import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetComponent; import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetComponent;
import io.github.thebusybiscuit.slimefun4.core.attributes.RecipeDisplayItem; import io.github.thebusybiscuit.slimefun4.core.attributes.RecipeDisplayItem;
@ -97,9 +97,9 @@ abstract class AbstractEnergyGenerator extends SlimefunItem implements Inventory
ItemStack item = fuel.getInput().clone(); ItemStack item = fuel.getInput().clone();
ItemMeta im = item.getItemMeta(); ItemMeta im = item.getItemMeta();
List<String> lore = new ArrayList<>(); List<String> lore = new ArrayList<>();
lore.add(ChatColor.translateAlternateColorCodes('&', "&8\u21E8 &7Lasts " + NumberUtils.getTimeLeft(fuel.getTicks() / 2))); lore.add(ChatColors.color("&8\u21E8 &7Lasts " + NumberUtils.getTimeLeft(fuel.getTicks() / 2)));
lore.add(ChatColor.translateAlternateColorCodes('&', "&8\u21E8 &e\u26A1 &7" + getEnergyProduction() * 2) + " J/s"); lore.add(ChatColors.color("&8\u21E8 &e\u26A1 &7" + getEnergyProduction() * 2) + " J/s");
lore.add(ChatColor.translateAlternateColorCodes('&', "&8\u21E8 &e\u26A1 &7" + DoubleHandler.getFancyDouble((double) fuel.getTicks() * getEnergyProduction()) + " J in total")); lore.add(ChatColors.color("&8\u21E8 &e\u26A1 &7" + DoubleHandler.getFancyDouble((double) fuel.getTicks() * getEnergyProduction()) + " J in total"));
im.setLore(lore); im.setLore(lore);
item.setItemMeta(im); item.setItemMeta(im);
list.add(item); list.add(item);

View File

@ -1,6 +1,7 @@
package me.mrCookieSlime.Slimefun.Objects.SlimefunItem.multiblocks; package me.mrCookieSlime.Slimefun.Objects.SlimefunItem.multiblocks;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.block.BlockFace; import org.bukkit.block.BlockFace;
import org.bukkit.block.Chest; import org.bukkit.block.Chest;
@ -11,86 +12,94 @@ import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.cscorelib2.inventory.InvUtils; import io.github.thebusybiscuit.cscorelib2.inventory.InvUtils;
import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction; import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction;
import io.github.thebusybiscuit.slimefun4.api.SlimefunAddon; import io.github.thebusybiscuit.slimefun4.api.SlimefunAddon;
import io.github.thebusybiscuit.slimefun4.core.MultiBlock;
import me.mrCookieSlime.Slimefun.SlimefunPlugin; import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunMachine; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunMachine;
import me.mrCookieSlime.Slimefun.Objects.handlers.MultiBlockInteractionHandler; import me.mrCookieSlime.Slimefun.Objects.handlers.MultiBlockInteractionHandler;
import me.mrCookieSlime.Slimefun.api.BlockStorage; import me.mrCookieSlime.Slimefun.api.BlockStorage;
import me.mrCookieSlime.Slimefun.api.Slimefun; import me.mrCookieSlime.Slimefun.api.Slimefun;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
/**
* A {@link MultiBlockMachine} is a {@link SlimefunItem} that is built in the {@link World}.
* It holds recipes and a {@link MultiBlock} object which represents its structure.
*
* @author TheBusyBiscuit
*
* @see MultiBlock
*
*/
public abstract class MultiBlockMachine extends SlimefunMachine { public abstract class MultiBlockMachine extends SlimefunMachine {
private static final BlockFace[] outputFaces = { private static final BlockFace[] outputFaces = { BlockFace.UP, BlockFace.NORTH, BlockFace.EAST, BlockFace.SOUTH, BlockFace.WEST };
BlockFace.UP,
BlockFace.NORTH,
BlockFace.EAST,
BlockFace.SOUTH,
BlockFace.WEST
};
public MultiBlockMachine(Category category, SlimefunItemStack item, ItemStack[] recipe, ItemStack[] machineRecipes, BlockFace trigger) { public MultiBlockMachine(Category category, SlimefunItemStack item, ItemStack[] recipe, ItemStack[] machineRecipes, BlockFace trigger) {
super(category, item, recipe, machineRecipes, trigger); super(category, item, recipe, machineRecipes, trigger);
} }
@Override @Override
public void register(SlimefunAddon addon) { public void register(SlimefunAddon addon) {
addItemHandler(getInteractionHandler()); addItemHandler(getInteractionHandler());
super.register(addon); super.register(addon);
} }
protected MultiBlockInteractionHandler getInteractionHandler() { protected MultiBlockInteractionHandler getInteractionHandler() {
return (p, mb, b) -> { return (p, mb, b) -> {
if (mb.equals(getMultiBlock())) { if (mb.equals(getMultiBlock())) {
if (!isDisabled() && SlimefunPlugin.getProtectionManager().hasPermission(p, b.getLocation(), ProtectableAction.ACCESS_INVENTORIES) && Slimefun.hasUnlocked(p, this, true)) { if (!isDisabled() && SlimefunPlugin.getProtectionManager().hasPermission(p, b.getLocation(), ProtectableAction.ACCESS_INVENTORIES) && Slimefun.hasUnlocked(p, this, true)) {
onInteract(p, b); onInteract(p, b);
} }
return true; return true;
} }
else return false; else return false;
}; };
} }
public abstract void onInteract(Player p, Block b); public abstract void onInteract(Player p, Block b);
// Overloaded method for finding a potential output chest. Fallbacks to the old system of putting the adding back into the dispenser. // Overloaded method for finding a potential output chest. Fallbacks to the old system of putting the adding back
// Optional last argument Inventory placeCheckerInv is for multiblock machines that create a dummy inventory to check if there's a space for the adding, // into the dispenser.
// i.e. Enhanced crafting table // Optional last argument Inventory placeCheckerInv is for multiblock machines that create a dummy inventory to
protected Inventory findOutputInventory(ItemStack adding, Block dispBlock, Inventory dispInv) { // check if there's a space for the adding,
return findOutputInventory(adding, dispBlock, dispInv, dispInv); // i.e. Enhanced crafting table
} protected Inventory findOutputInventory(ItemStack adding, Block dispBlock, Inventory dispInv) {
return findOutputInventory(adding, dispBlock, dispInv, dispInv);
protected Inventory findOutputInventory(ItemStack product, Block dispBlock, Inventory dispInv, Inventory placeCheckerInv) { }
Inventory outputInv = findOutputChest(dispBlock, product);
protected Inventory findOutputInventory(ItemStack product, Block dispBlock, Inventory dispInv, Inventory placeCheckerInv) {
// This if-clause will trigger if no suitable output chest was found. It's functionally the same as the old fit check for the dispenser, only refactored. Inventory outputInv = findOutputChest(dispBlock, product);
if (outputInv == null && InvUtils.fits(placeCheckerInv, product)) {
return dispInv; // This if-clause will trigger if no suitable output chest was found. It's functionally the same as the old fit
} // check for the dispenser, only refactored.
else { if (outputInv == null && InvUtils.fits(placeCheckerInv, product)) {
return outputInv; return dispInv;
} }
} else {
return outputInv;
protected Inventory findOutputChest(Block b, ItemStack output) { }
for (BlockFace face : outputFaces) { }
Block potentialOutput = b.getRelative(face);
protected Inventory findOutputChest(Block b, ItemStack output) {
if (potentialOutput.getType() == Material.CHEST) { for (BlockFace face : outputFaces) {
String id = BlockStorage.checkID(potentialOutput); Block potentialOutput = b.getRelative(face);
if (id != null && id.equals("OUTPUT_CHEST")) { if (potentialOutput.getType() == Material.CHEST) {
// Found the output chest! Now, let's check if we can fit the product in it. String id = BlockStorage.checkID(potentialOutput);
Inventory inv = ((Chest) potentialOutput.getState()).getInventory();
if (id != null && id.equals("OUTPUT_CHEST")) {
if (InvUtils.fits(inv, output)) { // Found the output chest! Now, let's check if we can fit the product in it.
return inv; Inventory inv = ((Chest) potentialOutput.getState()).getInventory();
}
} if (InvUtils.fits(inv, output)) {
} return inv;
} }
}
}
}
return null; return null;
} }

View File

@ -1,5 +1,7 @@
package me.mrCookieSlime.Slimefun.Objects.handlers; package me.mrCookieSlime.Slimefun.Objects.handlers;
import org.bukkit.entity.Player;
import io.github.thebusybiscuit.slimefun4.api.events.PlayerRightClickEvent; import io.github.thebusybiscuit.slimefun4.api.events.PlayerRightClickEvent;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SimpleSlimefunItem; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SimpleSlimefunItem;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
@ -17,6 +19,13 @@ import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
@FunctionalInterface @FunctionalInterface
public interface ItemUseHandler extends ItemHandler { public interface ItemUseHandler extends ItemHandler {
/**
* This function is triggered when a {@link Player} right clicks with the assigned {@link SlimefunItem}
* in his hand.
*
* @param e
* The {@link PlayerRightClickEvent} that was triggered
*/
void onRightClick(PlayerRightClickEvent e); void onRightClick(PlayerRightClickEvent e);
@Override @Override

View File

@ -10,6 +10,7 @@ import java.util.logging.Level;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Server;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -40,10 +41,16 @@ import io.github.thebusybiscuit.slimefun4.core.services.UpdaterService;
import io.github.thebusybiscuit.slimefun4.core.services.github.GitHubService; import io.github.thebusybiscuit.slimefun4.core.services.github.GitHubService;
import io.github.thebusybiscuit.slimefun4.core.services.metrics.MetricsService; import io.github.thebusybiscuit.slimefun4.core.services.metrics.MetricsService;
import io.github.thebusybiscuit.slimefun4.core.services.plugins.ThirdPartyPluginService; import io.github.thebusybiscuit.slimefun4.core.services.plugins.ThirdPartyPluginService;
import io.github.thebusybiscuit.slimefun4.implementation.items.altar.AncientAltar;
import io.github.thebusybiscuit.slimefun4.implementation.items.food.Cooler;
import io.github.thebusybiscuit.slimefun4.implementation.items.tools.GrapplingHook;
import io.github.thebusybiscuit.slimefun4.implementation.items.weapons.SeismicAxe;
import io.github.thebusybiscuit.slimefun4.implementation.items.weapons.VampireBlade;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.AncientAltarListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.AncientAltarListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.BackpackListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.BackpackListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.BlockListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.BlockListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.BlockPhysicsListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.BlockPhysicsListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.CoolerListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.DeathpointListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.DeathpointListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.DebugFishListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.DebugFishListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.DispenserListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.DispenserListener;
@ -57,6 +64,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.listeners.IronGolemList
import io.github.thebusybiscuit.slimefun4.implementation.listeners.ItemPickupListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.ItemPickupListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.MultiBlockListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.MultiBlockListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.PlayerProfileListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.PlayerProfileListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.SeismicAxeListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.SlimefunBootsListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.SlimefunBootsListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.SlimefunBowListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.SlimefunBowListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.SlimefunGuideListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.SlimefunGuideListener;
@ -64,6 +72,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.listeners.SlimefunItemC
import io.github.thebusybiscuit.slimefun4.implementation.listeners.SlimefunItemListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.SlimefunItemListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.SoulboundListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.SoulboundListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.TalismanListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.TalismanListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.VampireBladeListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.VanillaMachinesListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.VanillaMachinesListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.WitherListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.WitherListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.WorldListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.WorldListener;
@ -75,6 +84,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.tasks.ArmorTask;
import io.github.thebusybiscuit.slimefun4.implementation.tasks.SlimefunStartupTask; import io.github.thebusybiscuit.slimefun4.implementation.tasks.SlimefunStartupTask;
import io.github.thebusybiscuit.slimefun4.implementation.tasks.TickerTask; import io.github.thebusybiscuit.slimefun4.implementation.tasks.TickerTask;
import me.mrCookieSlime.CSCoreLibPlugin.CSCoreLib; import me.mrCookieSlime.CSCoreLibPlugin.CSCoreLib;
import me.mrCookieSlime.Slimefun.Lists.SlimefunItems;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AContainer; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AContainer;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AGenerator; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AGenerator;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AReactor; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AReactor;
@ -148,7 +158,7 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon {
registry.load(config); registry.load(config);
// Set up localization // Set up localization
local = new LocalizationService(this, config.getString("options.language")); local = new LocalizationService(this, config.getString("options.chat-prefix"), config.getString("options.language"));
// Setting up Networks // Setting up Networks
gpsNetwork = new GPSNetwork(); gpsNetwork = new GPSNetwork();
@ -199,6 +209,13 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon {
new WitherListener(this); new WitherListener(this);
new IronGolemListener(this); new IronGolemListener(this);
// Item-specific Listeners
new VampireBladeListener(this, (VampireBlade) SlimefunItems.BLADE_OF_VAMPIRES.getItem());
new CoolerListener(this, (Cooler) SlimefunItems.COOLER.getItem());
new SeismicAxeListener(this, (SeismicAxe) SlimefunItems.SEISMIC_AXE.getItem());
grapplingHookListener.register(this, (GrapplingHook) SlimefunItems.GRAPPLING_HOOK.getItem());
ancientAltarListener.register(this, (AncientAltar) SlimefunItems.ANCIENT_ALTAR.getItem());
bowListener.register(this); bowListener.register(this);
// Toggleable Listeners for performance reasons // Toggleable Listeners for performance reasons
@ -215,7 +232,7 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon {
} }
// Handle Slimefun Guide being given on Join // Handle Slimefun Guide being given on Join
new SlimefunGuideListener(this, config.getBoolean("options.give-guide-on-first-join")); new SlimefunGuideListener(this, config.getBoolean("guide.receive-on-first-join"));
// Load/Unload Worlds in Slimefun // Load/Unload Worlds in Slimefun
new WorldListener(this); new WorldListener(this);
@ -274,6 +291,12 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon {
} }
} }
/**
* This method checks for the {@link MinecraftVersion} of the {@link Server}.
* If the version is unsupported, a warning will be printed to the console.
*
* @return Whether the {@link MinecraftVersion} is unsupported
*/
private boolean isVersionUnsupported() { private boolean isVersionUnsupported() {
String currentVersion = ReflectionUtils.getVersion(); String currentVersion = ReflectionUtils.getVersion();
@ -329,6 +352,7 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon {
ticker.run(); ticker.run();
} }
// Save all Player Profiles that are still in memory
PlayerProfile.iterator().forEachRemaining(profile -> { PlayerProfile.iterator().forEachRemaining(profile -> {
if (profile.isDirty()) { if (profile.isDirty()) {
profile.save(); profile.save();

View File

@ -5,15 +5,11 @@ options:
# You can download the latest stable build here: https://thebusybiscuit.github.io/builds/TheBusyBiscuit/Slimefun4/stable/ # You can download the latest stable build here: https://thebusybiscuit.github.io/builds/TheBusyBiscuit/Slimefun4/stable/
auto-update: true auto-update: true
chat-prefix: '&a&lSlimefun 4 &7>'
armor-update-interval: 10 armor-update-interval: 10
give-guide-on-first-join: true
enable-armor-effects: true enable-armor-effects: true
prefix: '&a&lSlimefun &7>'
auto-save-delay-in-minutes: 10 auto-save-delay-in-minutes: 10
show-vanilla-recipes-in-guide: true
allow-free-creative-research: true
emerald-enchantment-limit: 2 emerald-enchantment-limit: 2
research-unlock-fireworks: true
legacy-ore-washer: false legacy-ore-washer: false
legacy-dust-washer: false legacy-dust-washer: false
legacy-ore-grinder: true legacy-ore-grinder: true
@ -23,6 +19,12 @@ options:
guide: guide:
default-view-book: false default-view-book: false
show-vanilla-recipes: true
receive-on-first-join: true
researches:
free-in-creative-mode: true
enable-fireworks: true
URID: URID:
info-delay: 3000 info-delay: 3000