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

Merge branch 'master' into experimental

This commit is contained in:
TheBusyBiscuit 2020-07-08 13:34:27 +02:00 committed by GitHub
commit d677c29298
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
65 changed files with 803 additions and 579 deletions

View File

@ -69,6 +69,8 @@
* Fixed an issue with moving androids getting stuck
* Changed recipe of Hazmat Suits
* Uranium can no longer be placed down
* Coolant Cells can no longer be placed on the ground
* Crafting Nether Ice Coolant Cells now results in 4 items
#### Fixes
* Fixed #2005
@ -97,6 +99,8 @@
* Fixed Slimefun Armor sometimes not applying its effects
* Fixed contributors losing their texture after restarts
* Fixed "korean" showing up as "null"
* Fixed an issue with moving androids getting stuck
* Fixed Cargo nodes sometimes preventing chunks from unloading
## Release Candidate 13 (16 Jun 2020)
https://thebusybiscuit.github.io/builds/TheBusyBiscuit/Slimefun4/stable/#13

View File

@ -60,7 +60,7 @@
<url>https://repo.destroystokyo.com/repository/maven-public/</url>
</repository>
<repository>
<id>worldedit-worldguard-repo</id>
<id>worldedit-repo</id>
<url>https://maven.sk89q.com/repo/</url>
</repository>
<repository>

View File

@ -54,7 +54,7 @@ public class GPSNetwork {
private final Map<UUID, Set<Location>> transmitters = new HashMap<>();
private final TeleportationManager teleportation = new TeleportationManager();
private final ResourceManager resourceManager = new ResourceManager(SlimefunPlugin.instance);
private final ResourceManager resourceManager = new ResourceManager(SlimefunPlugin.instance());
/**
* This method updates the status of a {@link GPSTransmitter}.
@ -256,7 +256,7 @@ public class GPSNetwork {
SlimefunPlugin.getLocalization().sendMessage(p, "gps.waypoint.new", true);
p.playSound(p.getLocation(), Sound.BLOCK_NOTE_BLOCK_PLING, 0.5F, 1F);
ChatInput.waitForPlayer(SlimefunPlugin.instance, p, message -> addWaypoint(p, message, l));
ChatInput.waitForPlayer(SlimefunPlugin.instance(), p, message -> addWaypoint(p, message, l));
});
}

View File

@ -225,6 +225,10 @@ public abstract class Network {
});
}
public Location getRegulator() {
return regulator;
}
public void tick() {
discoverStep();
}

View File

@ -372,7 +372,7 @@ public final class PlayerProfile {
return true;
}
Bukkit.getScheduler().runTaskAsynchronously(SlimefunPlugin.instance, () -> {
Bukkit.getScheduler().runTaskAsynchronously(SlimefunPlugin.instance(), () -> {
PlayerProfile pp = new PlayerProfile(p);
SlimefunPlugin.getRegistry().getPlayerProfiles().put(uuid, pp);
callback.accept(pp);
@ -393,7 +393,7 @@ public final class PlayerProfile {
public static boolean request(OfflinePlayer p) {
if (!SlimefunPlugin.getRegistry().getPlayerProfiles().containsKey(p.getUniqueId())) {
// Should probably prevent multiple requests for the same profile in the future
Bukkit.getScheduler().runTaskAsynchronously(SlimefunPlugin.instance, () -> {
Bukkit.getScheduler().runTaskAsynchronously(SlimefunPlugin.instance(), () -> {
PlayerProfile pp = new PlayerProfile(p);
SlimefunPlugin.getRegistry().getPlayerProfiles().put(p.getUniqueId(), pp);
});

View File

@ -0,0 +1,34 @@
package io.github.thebusybiscuit.slimefun4.core.attributes;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import io.github.thebusybiscuit.slimefun4.implementation.items.misc.BasicCircuitBoard;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.MobDropListener;
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
/**
* This interface, when attached to a {@link SlimefunItem}, provides an easy method for adding
* a % chance to drop for an {@link SlimefunItem} on {@link entityDeathEvent}, this chance is 0-100
* and used in conjunction with the MOB_DROP {@link RecipeType}.
*
* @author dNiym
*
* @see BasicCircuitBoard
* @see MobDropListener
*
*/
@FunctionalInterface
public interface RandomMobDrop extends ItemAttribute {
/**
* Implement this method to make the object have a variable chance of being
* added to the dropList when {@link EntityType} (specified in the recipe)
* is killed by the {@link Player}
*
* @return The integer chance (0-100%) {@link SlimefunItem} has to drop.
*/
int getMobDropChance();
}

View File

@ -14,6 +14,7 @@ import io.github.thebusybiscuit.cscorelib2.chat.ChatColors;
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.utils.PatternUtils;
import net.md_5.bungee.api.ChatColor;
/**
* This is just a simple helper class to provide static methods to the {@link Rechargeable}
@ -26,7 +27,7 @@ import io.github.thebusybiscuit.slimefun4.utils.PatternUtils;
*/
final class RechargeableHelper {
private static final NamespacedKey CHARGE_KEY = new NamespacedKey(SlimefunPlugin.instance, "item_charge");
private static final NamespacedKey CHARGE_KEY = new NamespacedKey(SlimefunPlugin.instance(), "item_charge");
private static final String LORE_PREFIX = ChatColors.color("&8\u21E8 &e\u26A1 &7");
private static final Pattern REGEX = Pattern.compile(ChatColors.color("(&c&o)?" + LORE_PREFIX) + "[0-9\\.]+ \\/ [0-9\\.]+ J");
@ -69,7 +70,8 @@ final class RechargeableHelper {
if (meta.hasLore()) {
for (String line : meta.getLore()) {
if (REGEX.matcher(line).matches()) {
return Float.parseFloat(PatternUtils.SLASH_SEPARATOR.split(line)[0].replace(LORE_PREFIX, ""));
String data = ChatColor.stripColor(PatternUtils.SLASH_SEPARATOR.split(line)[0].replace(LORE_PREFIX, ""));
return Float.parseFloat(data);
}
}
}

View File

@ -60,13 +60,19 @@ final class ContributorsMenu {
menu.addItem(46, ChestMenuUtils.getPreviousButton(p, page + 1, pages));
menu.addMenuClickHandler(46, (pl, slot, item, action) -> {
if (page > 0) open(pl, page - 1);
if (page > 0) {
open(pl, page - 1);
}
return false;
});
menu.addItem(52, ChestMenuUtils.getNextButton(p, page + 1, pages));
menu.addMenuClickHandler(52, (pl, slot, item, action) -> {
if (page + 1 < pages) open(pl, page + 1);
if (page + 1 < pages) {
open(pl, page + 1);
}
return false;
});

View File

@ -16,12 +16,12 @@ class FireworksOption implements SlimefunGuideOption<Boolean> {
@Override
public SlimefunAddon getAddon() {
return SlimefunPlugin.instance;
return SlimefunPlugin.instance();
}
@Override
public NamespacedKey getKey() {
return new NamespacedKey(SlimefunPlugin.instance, "research_fireworks");
return new NamespacedKey(SlimefunPlugin.instance(), "research_fireworks");
}
@Override

View File

@ -22,12 +22,12 @@ class GuideLayoutOption implements SlimefunGuideOption<SlimefunGuideLayout> {
@Override
public SlimefunAddon getAddon() {
return SlimefunPlugin.instance;
return SlimefunPlugin.instance();
}
@Override
public NamespacedKey getKey() {
return new NamespacedKey(SlimefunPlugin.instance, "guide_layout");
return new NamespacedKey(SlimefunPlugin.instance(), "guide_layout");
}
@Override

View File

@ -23,7 +23,7 @@ class PlayerLanguageOption implements SlimefunGuideOption<String> {
@Override
public SlimefunAddon getAddon() {
return SlimefunPlugin.instance;
return SlimefunPlugin.instance();
}
@Override
@ -93,7 +93,7 @@ class PlayerLanguageOption implements SlimefunGuideOption<String> {
String defaultLanguageString = SlimefunPlugin.getLocalization().getMessage(p, "languages.default");
menu.addItem(9, new CustomItem(defaultLanguage.getItem(), ChatColor.GRAY + defaultLanguageString + ChatColor.DARK_GRAY + " (" + defaultLanguage.getName(p) + ")", "", "&7\u21E8 &e" + SlimefunPlugin.getLocalization().getMessage(p, "guide.languages.select-default")), (pl, i, item, action) -> {
SlimefunPlugin.instance.getServer().getPluginManager().callEvent(new PlayerLanguageChangeEvent(pl, SlimefunPlugin.getLocalization().getLanguage(pl), defaultLanguage));
SlimefunPlugin.instance().getServer().getPluginManager().callEvent(new PlayerLanguageChangeEvent(pl, SlimefunPlugin.getLocalization().getLanguage(pl), defaultLanguage));
setSelectedOption(pl, guide, null);
SlimefunPlugin.getLocalization().sendMessage(pl, "guide.languages.updated", msg -> msg.replace("%lang%", defaultLanguageString));
@ -106,7 +106,7 @@ class PlayerLanguageOption implements SlimefunGuideOption<String> {
for (Language language : SlimefunPlugin.getLocalization().getLanguages()) {
menu.addItem(slot, new CustomItem(language.getItem(), ChatColor.GREEN + language.getName(p), "&b" + SlimefunPlugin.getLocalization().getProgress(language) + '%', "", "&7\u21E8 &e" + SlimefunPlugin.getLocalization().getMessage(p, "guide.languages.select")), (pl, i, item, action) -> {
SlimefunPlugin.instance.getServer().getPluginManager().callEvent(new PlayerLanguageChangeEvent(pl, SlimefunPlugin.getLocalization().getLanguage(pl), language));
SlimefunPlugin.instance().getServer().getPluginManager().callEvent(new PlayerLanguageChangeEvent(pl, SlimefunPlugin.getLocalization().getLanguage(pl), language));
setSelectedOption(pl, guide, language.getId());
String name = language.getName(pl);

View File

@ -1,6 +1,5 @@
package io.github.thebusybiscuit.slimefun4.core.networks.cargo;
import java.util.Deque;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
@ -8,23 +7,18 @@ import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
import java.util.logging.Level;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.slimefun4.api.network.Network;
import io.github.thebusybiscuit.slimefun4.api.network.NetworkComponent;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.utils.holograms.SimpleHologram;
import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config;
import me.mrCookieSlime.Slimefun.api.BlockStorage;
import me.mrCookieSlime.Slimefun.api.Slimefun;
import me.mrCookieSlime.Slimefun.api.inventory.DirtyChestMenu;
/**
* The {@link CargoNet} is a type of {@link Network} which deals with {@link ItemStack} transportation.
@ -49,7 +43,7 @@ public class CargoNet extends ChestTerminalNetwork {
private final Set<Location> inputNodes = new HashSet<>();
private final Set<Location> outputNodes = new HashSet<>();
private final Map<Location, Integer> roundRobin = new HashMap<>();
protected final Map<Location, Integer> roundRobin = new HashMap<>();
private int tickDelayThreshold = 0;
public static CargoNet getNetworkFromLocation(Location l) {
@ -182,7 +176,9 @@ public class CargoNet extends ChestTerminalNetwork {
}
SlimefunPlugin.getProfiler().scheduleEntries(1 + inputNodes.size());
Slimefun.runSync(() -> run(inputs, outputs, chestTerminalInputs, chestTerminalOutputs));
CargoNetworkTask runnable = new CargoNetworkTask(this, inputs, outputs, chestTerminalInputs, chestTerminalOutputs);
Slimefun.runSync(runnable);
}
}
@ -240,135 +236,6 @@ public class CargoNet extends ChestTerminalNetwork {
return output;
}
private void run(Map<Location, Integer> inputs, Map<Integer, List<Location>> outputs, Set<Location> chestTerminalInputs, Set<Location> chestTerminalOutputs) {
long timestamp = System.nanoTime();
// Chest Terminal Code
if (SlimefunPlugin.getThirdPartySupportService().isChestTerminalInstalled()) {
handleItemRequests(chestTerminalInputs, chestTerminalOutputs);
}
// All operations happen here: Everything gets iterated from the Input Nodes.
// (Apart from ChestTerminal Buses)
for (Map.Entry<Location, Integer> entry : inputs.entrySet()) {
long nodeTimestamp = System.nanoTime();
Location input = entry.getKey();
Optional<Block> attachedBlock = getAttachedBlock(input.getBlock());
if (attachedBlock.isPresent()) {
routeItems(input, attachedBlock.get(), entry.getValue(), outputs);
}
// This will prevent this timings from showing up for the Cargo Manager
timestamp += SlimefunPlugin.getProfiler().closeEntry(entry.getKey(), SlimefunItems.CARGO_INPUT_NODE.getItem(), nodeTimestamp);
}
// Chest Terminal Code
if (SlimefunPlugin.getThirdPartySupportService().isChestTerminalInstalled()) {
updateTerminals(chestTerminalInputs);
}
// Submit a timings report
SlimefunPlugin.getProfiler().closeEntry(regulator, SlimefunItems.CARGO_MANAGER.getItem(), timestamp);
}
private void routeItems(Location inputNode, Block inputTarget, int frequency, Map<Integer, List<Location>> outputNodes) {
AtomicReference<Object> inventory = new AtomicReference<>();
ItemStackAndInteger slot = CargoUtils.withdraw(inputNode.getBlock(), inputTarget, inventory);
if (slot == null) {
return;
}
ItemStack stack = slot.getItem();
int previousSlot = slot.getInt();
List<Location> outputs = outputNodes.get(frequency);
if (outputs != null) {
stack = distributeItem(stack, inputNode, outputs);
}
if (stack != null) {
Object inputInventory = inventory.get();
if (inputInventory instanceof DirtyChestMenu) {
DirtyChestMenu menu = (DirtyChestMenu) inputInventory;
if (menu.getItemInSlot(previousSlot) == null) {
menu.replaceExistingItem(previousSlot, stack);
}
else {
inputTarget.getWorld().dropItem(inputTarget.getLocation().add(0, 1, 0), stack);
}
}
if (inputInventory instanceof Inventory) {
Inventory inv = (Inventory) inputInventory;
if (inv.getItem(previousSlot) == null) {
inv.setItem(previousSlot, stack);
}
else {
inputTarget.getWorld().dropItem(inputTarget.getLocation().add(0, 1, 0), stack);
}
}
}
}
private ItemStack distributeItem(ItemStack stack, Location inputNode, List<Location> outputNodes) {
ItemStack item = stack;
Deque<Location> destinations = new LinkedList<>(outputNodes);
Config cfg = BlockStorage.getLocationInfo(inputNode);
boolean roundrobin = "true".equals(cfg.getString("round-robin"));
if (roundrobin) {
roundRobinSort(inputNode, destinations);
}
for (Location output : destinations) {
Optional<Block> target = getAttachedBlock(output.getBlock());
if (target.isPresent()) {
item = CargoUtils.insert(output.getBlock(), target.get(), item);
if (item == null) {
break;
}
}
}
return item;
}
/**
* This method sorts a given {@link Deque} of output node locations using a semi-accurate
* round-robin method.
*
* @param inputNode
* The {@link Location} of the input node
* @param outputNodes
* A {@link Deque} of {@link Location Locations} of the output nodes
*/
private void roundRobinSort(Location inputNode, Deque<Location> outputNodes) {
int index = roundRobin.getOrDefault(inputNode, 0);
if (index < outputNodes.size()) {
// Not ideal but actually not bad performance-wise over more elegant alternatives
for (int i = 0; i < index; i++) {
Location temp = outputNodes.removeFirst();
outputNodes.add(temp);
}
index++;
}
else {
index = 1;
}
roundRobin.put(inputNode, index);
}
/**
* This method returns the frequency a given node is set to.
* Should there be an {@link Exception} to this method it will fall back to zero in

View File

@ -0,0 +1,183 @@
package io.github.thebusybiscuit.slimefun4.core.networks.cargo;
import java.util.Deque;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config;
import me.mrCookieSlime.Slimefun.api.BlockStorage;
import me.mrCookieSlime.Slimefun.api.inventory.DirtyChestMenu;
/**
* The {@link CargoNetworkTask} is the actual {@link Runnable} responsible for moving {@link ItemStack ItemStacks}
* around the {@link CargoNet}.
*
* Inbefore this was just a method in the {@link CargoNet} class.
* However for aesthetic reasons but mainly to prevent the Cargo Task from showing up as
* "lambda:xyz-123" in timing reports... this was moved.
*
* @see CargoNet
* @see CargoUtils
* @see ChestTerminalNetwork
*
*/
class CargoNetworkTask implements Runnable {
private final CargoNet network;
private final Map<Location, Inventory> inventories = new HashMap<>();
private final Map<Location, Integer> inputs;
private final Map<Integer, List<Location>> outputs;
private final Set<Location> chestTerminalInputs;
private final Set<Location> chestTerminalOutputs;
CargoNetworkTask(CargoNet network, Map<Location, Integer> inputs, Map<Integer, List<Location>> outputs, Set<Location> chestTerminalInputs, Set<Location> chestTerminalOutputs) {
this.network = network;
this.inputs = inputs;
this.outputs = outputs;
this.chestTerminalInputs = chestTerminalInputs;
this.chestTerminalOutputs = chestTerminalOutputs;
}
@Override
public void run() {
long timestamp = System.nanoTime();
// Chest Terminal Code
if (SlimefunPlugin.getThirdPartySupportService().isChestTerminalInstalled()) {
network.handleItemRequests(inventories, chestTerminalInputs, chestTerminalOutputs);
}
// All operations happen here: Everything gets iterated from the Input Nodes.
// (Apart from ChestTerminal Buses)
for (Map.Entry<Location, Integer> entry : inputs.entrySet()) {
long nodeTimestamp = System.nanoTime();
Location input = entry.getKey();
Optional<Block> attachedBlock = network.getAttachedBlock(input);
if (attachedBlock.isPresent()) {
routeItems(input, attachedBlock.get(), entry.getValue(), outputs);
}
// This will prevent this timings from showing up for the Cargo Manager
timestamp += SlimefunPlugin.getProfiler().closeEntry(entry.getKey(), SlimefunItems.CARGO_INPUT_NODE.getItem(), nodeTimestamp);
}
// Chest Terminal Code
if (SlimefunPlugin.getThirdPartySupportService().isChestTerminalInstalled()) {
network.updateTerminals(chestTerminalInputs);
}
// Submit a timings report
SlimefunPlugin.getProfiler().closeEntry(network.getRegulator(), SlimefunItems.CARGO_MANAGER.getItem(), timestamp);
}
private void routeItems(Location inputNode, Block inputTarget, int frequency, Map<Integer, List<Location>> outputNodes) {
ItemStackAndInteger slot = CargoUtils.withdraw(inventories, inputNode.getBlock(), inputTarget);
if (slot == null) {
return;
}
ItemStack stack = slot.getItem();
int previousSlot = slot.getInt();
List<Location> destinations = outputNodes.get(frequency);
if (destinations != null) {
stack = distributeItem(stack, inputNode, destinations);
}
if (stack != null) {
Inventory inv = inventories.get(inputTarget.getLocation());
if (inv != null) {
if (inv.getItem(previousSlot) == null) {
inv.setItem(previousSlot, stack);
}
else {
inputTarget.getWorld().dropItem(inputTarget.getLocation().add(0, 1, 0), stack);
}
}
else {
DirtyChestMenu menu = CargoUtils.getChestMenu(inputTarget);
if (menu != null) {
if (menu.getItemInSlot(previousSlot) == null) {
menu.replaceExistingItem(previousSlot, stack);
}
else {
inputTarget.getWorld().dropItem(inputTarget.getLocation().add(0, 1, 0), stack);
}
}
}
}
}
private ItemStack distributeItem(ItemStack stack, Location inputNode, List<Location> outputNodes) {
ItemStack item = stack;
Deque<Location> destinations = new LinkedList<>(outputNodes);
Config cfg = BlockStorage.getLocationInfo(inputNode);
boolean roundrobin = "true".equals(cfg.getString("round-robin"));
if (roundrobin) {
roundRobinSort(inputNode, destinations);
}
for (Location output : destinations) {
Optional<Block> target = network.getAttachedBlock(output);
if (target.isPresent()) {
item = CargoUtils.insert(inventories, output.getBlock(), target.get(), item);
if (item == null) {
break;
}
}
}
return item;
}
/**
* This method sorts a given {@link Deque} of output node locations using a semi-accurate
* round-robin method.
*
* @param inputNode
* The {@link Location} of the input node
* @param outputNodes
* A {@link Deque} of {@link Location Locations} of the output nodes
*/
private void roundRobinSort(Location inputNode, Deque<Location> outputNodes) {
int index = network.roundRobin.getOrDefault(inputNode, 0);
if (index < outputNodes.size()) {
// Not ideal but actually not bad performance-wise over more elegant alternatives
for (int i = 0; i < index; i++) {
Location temp = outputNodes.removeFirst();
outputNodes.add(temp);
}
index++;
}
else {
index = 1;
}
network.roundRobin.put(inputNode, index);
}
}

View File

@ -1,10 +1,9 @@
package io.github.thebusybiscuit.slimefun4.core.networks.cargo;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
import java.util.Map;
import java.util.logging.Level;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Tag;
import org.bukkit.block.Block;
@ -83,15 +82,23 @@ final class CargoUtils {
return false;
}
static ItemStack withdraw(Block node, Block target, ItemStack template) {
static ItemStack withdraw(Map<Location, Inventory> inventories, Block node, Block target, ItemStack template) {
DirtyChestMenu menu = getChestMenu(target);
if (menu == null) {
if (hasInventory(target)) {
Inventory inventory = inventories.get(target.getLocation());
if (inventory != null) {
return withdrawFromVanillaInventory(node, template, inventory);
}
BlockState state = target.getState();
if (state instanceof InventoryHolder) {
return withdrawFromVanillaInventory(node, template, ((InventoryHolder) state).getInventory());
inventory = ((InventoryHolder) state).getInventory();
inventories.put(target.getLocation(), inventory);
return withdrawFromVanillaInventory(node, template, inventory);
}
}
@ -135,10 +142,10 @@ final class CargoUtils {
ItemStackWrapper wrapper = new ItemStackWrapper(template);
for (int slot = minSlot; slot < maxSlot; slot++) {
// Changes to this ItemStack are synchronized with the Item in the Inventory
// Changes to these ItemStacks are synchronized with the Item in the Inventory
ItemStack itemInSlot = contents[slot];
if (SlimefunUtils.isItemSimilar(itemInSlot, wrapper, true) && matchesFilter(node, itemInSlot)) {
if (SlimefunUtils.isItemSimilar(itemInSlot, wrapper, true, false) && matchesFilter(node, itemInSlot)) {
if (itemInSlot.getAmount() > template.getAmount()) {
itemInSlot.setAmount(itemInSlot.getAmount() - template.getAmount());
return template;
@ -154,7 +161,7 @@ final class CargoUtils {
return null;
}
static ItemStackAndInteger withdraw(Block node, Block target, AtomicReference<Object> inventory) {
static ItemStackAndInteger withdraw(Map<Location, Inventory> inventories, Block node, Block target) {
DirtyChestMenu menu = getChestMenu(target);
if (menu != null) {
@ -163,45 +170,55 @@ final class CargoUtils {
if (matchesFilter(node, is)) {
menu.replaceExistingItem(slot, null);
inventory.set(menu);
return new ItemStackAndInteger(is, slot);
}
}
}
else if (hasInventory(target)) {
Inventory inventory = inventories.get(target.getLocation());
if (inventory != null) {
return withdrawFromVanillaInventory(node, inventory);
}
BlockState state = target.getState();
if (state instanceof InventoryHolder) {
Inventory inv = ((InventoryHolder) state).getInventory();
ItemStack[] contents = inv.getContents();
int minSlot = 0;
int maxSlot = contents.length;
if (inv instanceof FurnaceInventory) {
minSlot = 2;
maxSlot = 3;
}
else if (inv instanceof BrewerInventory) {
maxSlot = 3;
}
for (int slot = minSlot; slot < maxSlot; slot++) {
ItemStack is = contents[slot];
if (matchesFilter(node, is)) {
inv.setItem(slot, null);
inventory.set(inv);
return new ItemStackAndInteger(is, slot);
}
}
inventory = ((InventoryHolder) state).getInventory();
inventories.put(target.getLocation(), inventory);
return withdrawFromVanillaInventory(node, inventory);
}
}
return null;
}
static ItemStack insert(Block node, Block target, ItemStack stack) {
private static ItemStackAndInteger withdrawFromVanillaInventory(Block node, Inventory inv) {
ItemStack[] contents = inv.getContents();
int minSlot = 0;
int maxSlot = contents.length;
if (inv instanceof FurnaceInventory) {
minSlot = 2;
maxSlot = 3;
}
else if (inv instanceof BrewerInventory) {
maxSlot = 3;
}
for (int slot = minSlot; slot < maxSlot; slot++) {
ItemStack is = contents[slot];
if (matchesFilter(node, is)) {
inv.setItem(slot, null);
return new ItemStackAndInteger(is, slot);
}
}
return null;
}
static ItemStack insert(Map<Location, Inventory> inventories, Block node, Block target, ItemStack stack) {
if (!matchesFilter(node, stack)) {
return stack;
}
@ -210,10 +227,18 @@ final class CargoUtils {
if (menu == null) {
if (hasInventory(target)) {
Inventory inventory = inventories.get(target.getLocation());
if (inventory != null) {
return insertIntoVanillaInventory(stack, inventory);
}
BlockState state = target.getState();
if (state instanceof InventoryHolder) {
return insertIntoVanillaInventory(stack, ((InventoryHolder) state).getInventory());
inventory = ((InventoryHolder) state).getInventory();
inventories.put(target.getLocation(), inventory);
return insertIntoVanillaInventory(stack, inventory);
}
}
@ -251,7 +276,7 @@ final class CargoUtils {
return stack;
}
static ItemStack insertIntoVanillaInventory(ItemStack stack, Inventory inv) {
private static ItemStack insertIntoVanillaInventory(ItemStack stack, Inventory inv) {
ItemStack[] contents = inv.getContents();
int minSlot = 0;
int maxSlot = contents.length;
@ -359,9 +384,10 @@ final class CargoUtils {
}
// Store the returned Config instance to avoid heavy calls
Config blockInfo = BlockStorage.getLocationInfo(block.getLocation());
String id = blockInfo.getString("id");
Config blockData = BlockStorage.getLocationInfo(block.getLocation());
String id = blockData.getString("id");
// Cargo Output nodes have no filter actually
if (id.equals("CARGO_NODE_OUTPUT")) {
return true;
}
@ -373,43 +399,9 @@ final class CargoUtils {
return false;
}
boolean lore = "true".equals(blockInfo.getString("filter-lore"));
ItemStackWrapper wrapper = new ItemStackWrapper(item);
if ("whitelist".equals(blockInfo.getString("filter-type"))) {
List<ItemStack> templateItems = new LinkedList<>();
for (int slot : FILTER_SLOTS) {
ItemStack template = menu.getItemInSlot(slot);
if (template != null) {
templateItems.add(template);
}
}
if (templateItems.isEmpty()) {
return false;
}
for (ItemStack stack : templateItems) {
if (SlimefunUtils.isItemSimilar(wrapper, stack, lore)) {
return true;
}
}
return false;
}
else {
for (int slot : FILTER_SLOTS) {
ItemStack itemInSlot = menu.getItemInSlot(slot);
if (itemInSlot != null && SlimefunUtils.isItemSimilar(wrapper, itemInSlot, lore, false)) {
return false;
}
}
return true;
}
boolean lore = "true".equals(blockData.getString("filter-lore"));
boolean allowByDefault = !"whitelist".equals(blockData.getString("filter-type"));
return matchesFilterList(item, menu, lore, allowByDefault);
}
catch (Exception x) {
Slimefun.getLogger().log(Level.SEVERE, x, () -> "An Exception occurred while trying to filter items for a Cargo Node (" + id + ") at " + new BlockPosition(block));
@ -417,6 +409,27 @@ final class CargoUtils {
}
}
private static boolean matchesFilterList(ItemStack item, BlockMenu menu, boolean respectLore, boolean defaultValue) {
ItemStackWrapper wrapper = null;
for (int slot : FILTER_SLOTS) {
ItemStack stack = menu.getItemInSlot(slot);
if (stack != null) {
if (wrapper == null) {
// Only create this as needed to save performance
wrapper = new ItemStackWrapper(item);
}
if (SlimefunUtils.isItemSimilar(stack, wrapper, respectLore, false)) {
return !defaultValue;
}
}
}
return defaultValue;
}
/**
* Get the whitelist/blacklist slots in a Cargo Input Node. If you wish to access the items
* in the cargo (without hardcoding the slots in case of change) then you can use this method.

View File

@ -12,7 +12,6 @@ import java.util.Map;
import java.util.Optional;
import java.util.Queue;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
import org.bukkit.Location;
import org.bukkit.Material;
@ -69,25 +68,29 @@ abstract class ChestTerminalNetwork extends Network {
super(SlimefunPlugin.getNetworkManager(), regulator);
}
protected Optional<Block> getAttachedBlock(Block block) {
if (block.getType() == Material.PLAYER_WALL_HEAD) {
BlockFace cached = connectorCache.get(block.getLocation());
protected Optional<Block> getAttachedBlock(Location l) {
if (l.getWorld().isChunkLoaded(l.getBlockX() >> 4, l.getBlockZ() >> 4)) {
Block block = l.getBlock();
if (cached != null) {
return Optional.of(block.getRelative(cached));
if (block.getType() == Material.PLAYER_WALL_HEAD) {
BlockFace cached = connectorCache.get(l);
if (cached != null) {
return Optional.of(block.getRelative(cached));
}
BlockFace face = ((Directional) block.getBlockData()).getFacing().getOppositeFace();
connectorCache.put(l, face);
return Optional.of(block.getRelative(face));
}
BlockFace face = ((Directional) block.getBlockData()).getFacing().getOppositeFace();
connectorCache.put(block.getLocation(), face);
return Optional.of(block.getRelative(face));
}
return Optional.empty();
}
protected void handleItemRequests(Set<Location> providers, Set<Location> destinations) {
collectImportRequests();
collectExportRequests();
protected void handleItemRequests(Map<Location, Inventory> inventories, Set<Location> providers, Set<Location> destinations) {
collectImportRequests(inventories);
collectExportRequests(inventories);
collectTerminalRequests();
Iterator<ItemRequest> iterator = itemRequests.iterator();
@ -99,10 +102,10 @@ abstract class ChestTerminalNetwork extends Network {
switch (request.getDirection()) {
case INSERT:
distributeInsertionRequest(request, menu, iterator, destinations);
distributeInsertionRequest(inventories, request, menu, iterator, destinations);
break;
case WITHDRAW:
collectExtractionRequest(request, menu, iterator, providers);
collectExtractionRequest(inventories, request, menu, iterator, providers);
break;
default:
break;
@ -111,14 +114,14 @@ abstract class ChestTerminalNetwork extends Network {
}
}
private void distributeInsertionRequest(ItemRequest request, BlockMenu terminal, Iterator<ItemRequest> iterator, Set<Location> destinations) {
private void distributeInsertionRequest(Map<Location, Inventory> inventories, ItemRequest request, BlockMenu terminal, Iterator<ItemRequest> iterator, Set<Location> destinations) {
ItemStack item = request.getItem();
for (Location l : destinations) {
Optional<Block> target = getAttachedBlock(l.getBlock());
Optional<Block> target = getAttachedBlock(l);
if (target.isPresent()) {
item = CargoUtils.insert(l.getBlock(), target.get(), item);
item = CargoUtils.insert(inventories, l.getBlock(), target.get(), item);
if (item == null) {
terminal.replaceExistingItem(request.getSlot(), null);
@ -134,7 +137,7 @@ abstract class ChestTerminalNetwork extends Network {
iterator.remove();
}
private void collectExtractionRequest(ItemRequest request, BlockMenu terminal, Iterator<ItemRequest> iterator, Set<Location> providers) {
private void collectExtractionRequest(Map<Location, Inventory> inventories, ItemRequest request, BlockMenu terminal, Iterator<ItemRequest> iterator, Set<Location> providers) {
int slot = request.getSlot();
ItemStack prevStack = terminal.getItemInSlot(slot);
@ -147,10 +150,10 @@ abstract class ChestTerminalNetwork extends Network {
ItemStack item = request.getItem();
for (Location l : providers) {
Optional<Block> target = getAttachedBlock(l.getBlock());
Optional<Block> target = getAttachedBlock(l);
if (target.isPresent()) {
ItemStack is = CargoUtils.withdraw(l.getBlock(), target.get(), item);
ItemStack is = CargoUtils.withdraw(inventories, l.getBlock(), target.get(), item);
if (is != null) {
if (stack == null) {
@ -184,7 +187,7 @@ abstract class ChestTerminalNetwork extends Network {
iterator.remove();
}
private void collectImportRequests() {
private void collectImportRequests(Map<Location, Inventory> inventories) {
SlimefunItem item = SlimefunItem.getByID("CT_IMPORT_BUS");
for (Location bus : imports) {
@ -192,10 +195,10 @@ abstract class ChestTerminalNetwork extends Network {
BlockMenu menu = BlockStorage.getInventory(bus);
if (menu.getItemInSlot(17) == null) {
Optional<Block> target = getAttachedBlock(bus.getBlock());
Optional<Block> target = getAttachedBlock(bus);
if (target.isPresent()) {
ItemStackAndInteger stack = CargoUtils.withdraw(bus.getBlock(), target.get(), new AtomicReference<>());
ItemStackAndInteger stack = CargoUtils.withdraw(inventories, bus.getBlock(), target.get());
if (stack != null) {
menu.replaceExistingItem(17, stack.getItem());
@ -211,7 +214,7 @@ abstract class ChestTerminalNetwork extends Network {
}
}
private void collectExportRequests() {
private void collectExportRequests(Map<Location, Inventory> inventories) {
SlimefunItem item = SlimefunItem.getByID("CT_EXPORT_BUS");
for (Location bus : exports) {
@ -219,10 +222,10 @@ abstract class ChestTerminalNetwork extends Network {
BlockMenu menu = BlockStorage.getInventory(bus);
if (menu.getItemInSlot(17) != null) {
Optional<Block> target = getAttachedBlock(bus.getBlock());
Optional<Block> target = getAttachedBlock(bus);
if (target.isPresent()) {
menu.replaceExistingItem(17, CargoUtils.insert(bus.getBlock(), target.get(), menu.getItemInSlot(17)));
menu.replaceExistingItem(17, CargoUtils.insert(inventories, bus.getBlock(), target.get(), menu.getItemInSlot(17)));
}
}
@ -231,7 +234,10 @@ abstract class ChestTerminalNetwork extends Network {
for (int slot : slots) {
ItemStack template = menu.getItemInSlot(slot);
if (template != null) items.add(new CustomItem(template, 1));
if (template != null) {
items.add(new CustomItem(template, 1));
}
}
if (!items.isEmpty()) {
@ -339,7 +345,7 @@ abstract class ChestTerminalNetwork extends Network {
List<ItemStackAndInteger> items = new LinkedList<>();
for (Location l : providers) {
Optional<Block> block = getAttachedBlock(l.getBlock());
Optional<Block> block = getAttachedBlock(l);
if (block.isPresent()) {
Block target = block.get();

View File

@ -56,9 +56,9 @@ class GitHubTask implements Runnable {
}
}
if (requests >= MAX_REQUESTS_PER_MINUTE && SlimefunPlugin.instance != null && SlimefunPlugin.instance.isEnabled()) {
if (requests >= MAX_REQUESTS_PER_MINUTE && SlimefunPlugin.instance() != null && SlimefunPlugin.instance().isEnabled()) {
// Slow down API requests and wait a minute after more than x requests were made
Bukkit.getScheduler().runTaskLaterAsynchronously(SlimefunPlugin.instance, this::grabTextures, 2 * 60 * 20L);
Bukkit.getScheduler().runTaskLaterAsynchronously(SlimefunPlugin.instance(), this::grabTextures, 2 * 60 * 20L);
}
for (GitHubConnector connector : gitHubService.getConnectors()) {
@ -94,14 +94,14 @@ class GitHubTask implements Runnable {
// Retry after 5 minutes if it was rate-limiting
if (x.getMessage().contains("429")) {
Bukkit.getScheduler().runTaskLaterAsynchronously(SlimefunPlugin.instance, this::grabTextures, 5 * 60 * 20L);
Bukkit.getScheduler().runTaskLaterAsynchronously(SlimefunPlugin.instance(), this::grabTextures, 5 * 60 * 20L);
}
return -1;
}
catch (TooManyRequestsException x) {
Slimefun.getLogger().log(Level.WARNING, "Received a rate-limit from mojang.com, retrying in 4 minutes");
Bukkit.getScheduler().runTaskLaterAsynchronously(SlimefunPlugin.instance, this::grabTextures, 4 * 60 * 20L);
Bukkit.getScheduler().runTaskLaterAsynchronously(SlimefunPlugin.instance(), this::grabTextures, 4 * 60 * 20L);
return -1;
}

View File

@ -16,7 +16,7 @@ class PlaceholderAPIHook extends PlaceholderExpansion {
@Override
public String getAuthor() {
return SlimefunPlugin.instance.getDescription().getAuthors().toString();
return SlimefunPlugin.instance().getDescription().getAuthors().toString();
}
@Override
@ -26,7 +26,7 @@ class PlaceholderAPIHook extends PlaceholderExpansion {
@Override
public String getVersion() {
return SlimefunPlugin.instance.getDescription().getVersion();
return SlimefunPlugin.instance().getDescription().getVersion();
}
@Override

View File

@ -25,10 +25,6 @@ class PerformanceSummary {
private static final int MIN_ITEMS = 3;
private static final int MAX_ITEMS = 10;
// A minecraft server tick is 50ms and Slimefun ticks are stretched across
// two ticks (sync and async blocks), so we use 100ms as a reference here
static final int MAX_TICK_DURATION = 100;
private final SlimefunProfiler profiler;
private final PerformanceRating rating;
private final long totalElapsedTime;

View File

@ -10,7 +10,6 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Level;
import org.apache.commons.lang.Validate;
import org.bukkit.Chunk;
@ -25,7 +24,6 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.tasks.TickerTask;
import io.github.thebusybiscuit.slimefun4.utils.NumberUtils;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.api.Slimefun;
/**
* The {@link SlimefunProfiler} works closely to the {@link TickerTask} and is
@ -41,7 +39,11 @@ import me.mrCookieSlime.Slimefun.api.Slimefun;
*/
public class SlimefunProfiler {
private final ExecutorService executor = Executors.newFixedThreadPool(3);
// A minecraft server tick is 50ms and Slimefun ticks are stretched across
// two ticks (sync and async blocks), so we use 100ms as a reference here
private static final int MAX_TICK_DURATION = 100;
private final ExecutorService executor = Executors.newFixedThreadPool(4);
private final AtomicBoolean running = new AtomicBoolean(false);
private final AtomicInteger queued = new AtomicInteger(0);
@ -125,7 +127,7 @@ public class SlimefunProfiler {
public void stop() {
running.set(false);
if (SlimefunPlugin.instance == null || !SlimefunPlugin.instance.isEnabled()) {
if (SlimefunPlugin.instance() == null || !SlimefunPlugin.instance().isEnabled()) {
// Slimefun has been disabled
return;
}
@ -135,13 +137,9 @@ public class SlimefunProfiler {
// Wait for all timing results to come in
while (queued.get() > 0 && !running.get()) {
try {
Thread.sleep(1);
}
catch (InterruptedException e) {
Slimefun.getLogger().log(Level.SEVERE, "A waiting Thread was interrupted", e);
Thread.currentThread().interrupt();
}
// Ideally we would wait some time here but the ticker task may be faster
// than 1ms, so it would halt this summary for up to 7 minutes
// Not perfect performance-wise but this is a seperate Thread anyway
}
if (running.get()) {
@ -253,7 +251,7 @@ public class SlimefunProfiler {
protected float getPercentageOfTick() {
float millis = totalElapsedTime / 1000000.0F;
float fraction = (millis * 100.0F) / PerformanceSummary.MAX_TICK_DURATION;
float fraction = (millis * 100.0F) / MAX_TICK_DURATION;
return Math.round((fraction * 100.0F) / 100.0F);
}

View File

@ -46,7 +46,6 @@ import io.github.thebusybiscuit.slimefun4.core.services.plugins.ThirdPartyPlugin
import io.github.thebusybiscuit.slimefun4.core.services.profiler.SlimefunProfiler;
import io.github.thebusybiscuit.slimefun4.implementation.items.altar.AncientAltar;
import io.github.thebusybiscuit.slimefun4.implementation.items.backpacks.Cooler;
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.BasicCircuitBoard;
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.reactors.Reactor;
import io.github.thebusybiscuit.slimefun4.implementation.items.tools.GrapplingHook;
import io.github.thebusybiscuit.slimefun4.implementation.items.weapons.SeismicAxe;
@ -107,7 +106,7 @@ import me.mrCookieSlime.Slimefun.api.inventory.UniversalBlockMenu;
*/
public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon {
public static SlimefunPlugin instance;
private static SlimefunPlugin instance;
private MinecraftVersion minecraftVersion = MinecraftVersion.UNKNOWN;
@ -331,7 +330,7 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon {
@Override
public void onDisable() {
// Slimefun never loaded successfully, so we don't even bother doing stuff here
if (instance == null || minecraftVersion == MinecraftVersion.UNIT_TEST) {
if (instance() == null || minecraftVersion == MinecraftVersion.UNIT_TEST) {
return;
}
@ -432,7 +431,7 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon {
new BeeListener(this);
}
new MobDropListener(this, (BasicCircuitBoard) SlimefunItems.BASIC_CIRCUIT_BOARD.getItem());
new MobDropListener(this);
// Item-specific Listeners
new VampireBladeListener(this, (VampireBlade) SlimefunItems.BLADE_OF_VAMPIRES.getItem());
@ -484,6 +483,10 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon {
}
}
public static SlimefunPlugin instance() {
return instance;
}
public static Config getCfg() {
return instance.config;
}

View File

@ -35,7 +35,7 @@ import me.mrCookieSlime.Slimefun.api.Slimefun;
public class BookSlimefunGuide implements SlimefunGuideImplementation {
private final NamespacedKey guideSearch = new NamespacedKey(SlimefunPlugin.instance, "search");
private final NamespacedKey guideSearch = new NamespacedKey(SlimefunPlugin.instance(), "search");
@Override
public SlimefunGuideLayout getLayout() {
@ -53,7 +53,7 @@ public class BookSlimefunGuide implements SlimefunGuideImplementation {
}
private void openBook(Player p, PlayerProfile profile, List<ChatComponent> lines, boolean backButton) {
CustomBookInterface book = new CustomBookInterface(SlimefunPlugin.instance);
CustomBookInterface book = new CustomBookInterface(SlimefunPlugin.instance());
book.setTitle(SlimefunPlugin.getLocalization().getMessage(p, "guide.title.main"));
for (int i = 0; i < lines.size(); i = i + 10) {
@ -63,7 +63,7 @@ public class BookSlimefunGuide implements SlimefunGuideImplementation {
header.setClickEvent(new ClickEvent(guideSearch, player -> Slimefun.runSync(() -> {
SlimefunPlugin.getLocalization().sendMessage(player, "guide.search.message");
ChatInput.waitForPlayer(SlimefunPlugin.instance, player, msg -> SlimefunGuide.openSearch(profile, msg, true, true));
ChatInput.waitForPlayer(SlimefunPlugin.instance(), player, msg -> SlimefunGuide.openSearch(profile, msg, true, true));
}, 1)));
page.append(header);
@ -77,7 +77,7 @@ public class BookSlimefunGuide implements SlimefunGuideImplementation {
if (backButton) {
ChatComponent button = new ChatComponent(ChatColor.DARK_BLUE + "\u21E6 " + SlimefunPlugin.getLocalization().getMessage(p, "guide.back.title"));
button.setHoverEvent(new HoverEvent(ChatColor.DARK_BLUE + "\u21E6 " + SlimefunPlugin.getLocalization().getMessage(p, "guide.back.title"), "", ChatColor.GRAY + SlimefunPlugin.getLocalization().getMessage(p, "guide.back.guide")));
button.setClickEvent(new ClickEvent(new NamespacedKey(SlimefunPlugin.instance, "slimefun_guide"), pl -> openMainMenu(profile, 1)));
button.setClickEvent(new ClickEvent(new NamespacedKey(SlimefunPlugin.instance(), "slimefun_guide"), pl -> openMainMenu(profile, 1)));
page.append(button);
}
@ -189,7 +189,7 @@ public class BookSlimefunGuide implements SlimefunGuideImplementation {
}
private void appendSlimefunItem(Category category, int page, Player p, PlayerProfile profile, SlimefunItem item, List<ChatComponent> items) {
NamespacedKey key = new NamespacedKey(SlimefunPlugin.instance, item.getID().toLowerCase(Locale.ROOT));
NamespacedKey key = new NamespacedKey(SlimefunPlugin.instance(), item.getID().toLowerCase(Locale.ROOT));
if (!Slimefun.hasUnlocked(p, item, false) && item.getResearch() != null) {
Research research = item.getResearch();

View File

@ -561,7 +561,7 @@ public class ChestSlimefunGuide implements SlimefunGuideImplementation {
pl.closeInventory();
SlimefunPlugin.getLocalization().sendMessage(pl, "guide.search.message");
ChatInput.waitForPlayer(SlimefunPlugin.instance, pl, msg -> SlimefunGuide.openSearch(profile, msg, isSurvivalMode(), isSurvivalMode()));
ChatInput.waitForPlayer(SlimefunPlugin.instance(), pl, msg -> SlimefunGuide.openSearch(profile, msg, isSurvivalMode(), isSurvivalMode()));
return false;
});

View File

@ -42,7 +42,7 @@ class RecipeChoiceTask implements Runnable {
public void start(Inventory inv) {
Validate.notNull(inv, "Inventory must not be null");
inventory = inv;
id = Bukkit.getScheduler().runTaskTimerAsynchronously(SlimefunPlugin.instance, this, 0, UPDATE_INTERVAL).getTaskId();
id = Bukkit.getScheduler().runTaskTimerAsynchronously(SlimefunPlugin.instance(), this, 0, UPDATE_INTERVAL).getTaskId();
}
public void add(int slot, MaterialChoice choice) {

View File

@ -20,7 +20,7 @@ public class AncientPedestal extends SlimefunItem {
Item stack = listener.findItem(b);
if (stack != null) {
stack.removeMetadata("no_pickup", SlimefunPlugin.instance);
stack.removeMetadata("no_pickup", SlimefunPlugin.instance());
b.getWorld().dropItem(b.getLocation(), listener.fixItemStack(stack.getItemStack(), stack.getCustomName()));
stack.remove();
}

View File

@ -57,10 +57,10 @@ public abstract class ButcherAndroid extends ProgrammableAndroid {
if (attack) {
if (n.hasMetadata(METADATA_KEY)) {
n.removeMetadata(METADATA_KEY, SlimefunPlugin.instance);
n.removeMetadata(METADATA_KEY, SlimefunPlugin.instance());
}
n.setMetadata(METADATA_KEY, new FixedMetadataValue(SlimefunPlugin.instance, new AndroidInstance(this, b)));
n.setMetadata(METADATA_KEY, new FixedMetadataValue(SlimefunPlugin.instance(), new AndroidInstance(this, b)));
((LivingEntity) n).damage(damage);
break;

View File

@ -441,7 +441,7 @@ public abstract class ProgrammableAndroid extends SlimefunItem implements Invent
SlimefunPlugin.getLocalization().sendMessages(p, "android.scripts.enter-name");
int id = nextId;
ChatInput.waitForPlayer(SlimefunPlugin.instance, p, msg -> {
ChatInput.waitForPlayer(SlimefunPlugin.instance(), p, msg -> {
Script.upload(p, getAndroidType(), id, msg, code);
SlimefunPlugin.getLocalization().sendMessages(p, "android.scripts.uploaded");
openScriptDownloader(p, b, page);

View File

@ -98,7 +98,7 @@ public class Composter extends SimpleSlimefunItem<BlockUseHandler> implements Re
pushItem(b, output.clone());
});
tasks.execute(SlimefunPlugin.instance);
tasks.execute(SlimefunPlugin.instance());
}
else {
SlimefunPlugin.getLocalization().sendMessage(p, "machines.wrong-item", true);

View File

@ -16,6 +16,10 @@ public class UnplaceableBlock extends SimpleSlimefunItem<ItemUseHandler> impleme
super(category, item, recipeType, recipe);
}
public UnplaceableBlock(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe, ItemStack recipeOutput) {
super(category, item, recipeType, recipe, recipeOutput);
}
@Override
public ItemUseHandler getItemHandler() {
return PlayerRightClickEvent::cancel;

View File

@ -11,8 +11,8 @@ import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.reactors.Reactor;
import io.github.thebusybiscuit.slimefun4.implementation.items.misc.CoolantCell;
import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils;
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
@ -74,18 +74,27 @@ public class ReactorAccessPort extends SlimefunItem {
@Override
public int[] getSlotsAccessedByItemTransport(ItemTransportFlow flow) {
if (flow == ItemTransportFlow.INSERT) return getInputSlots();
else return getOutputSlots();
if (flow == ItemTransportFlow.INSERT) {
return getInputSlots();
}
else {
return getOutputSlots();
}
}
@Override
public int[] getSlotsAccessedByItemTransport(DirtyChestMenu menu, ItemTransportFlow flow, ItemStack item) {
if (flow == ItemTransportFlow.INSERT) {
if (SlimefunUtils.isItemSimilar(item, SlimefunItems.REACTOR_COOLANT_CELL, true)) return getCoolantSlots();
else if (SlimefunUtils.isItemSimilar(item, SlimefunItems.NETHER_ICE_COOLANT_CELL, true)) return getCoolantSlots();
else return getFuelSlots();
if (SlimefunItem.getByItem(item) instanceof CoolantCell) {
return getCoolantSlots();
}
else {
return getFuelSlots();
}
}
else {
return getOutputSlots();
}
else return getOutputSlots();
}
};
@ -157,12 +166,11 @@ public class ReactorAccessPort extends SlimefunItem {
}
private BlockMenu getReactor(Location l) {
Location reactorL = new Location(l.getWorld(), l.getX(), l.getY() - 3, l.getZ());
SlimefunItem item = BlockStorage.check(reactorL.getBlock());
Location location = new Location(l.getWorld(), l.getX(), l.getY() - 3, l.getZ());
SlimefunItem item = BlockStorage.check(location.getBlock());
if (item instanceof Reactor) {
return BlockStorage.getInventory(reactorL);
return BlockStorage.getInventory(location);
}
return null;

View File

@ -63,7 +63,7 @@ public class WitherAssembler extends SimpleSlimefunItem<BlockTicker> implements
@Override
public void newInstance(BlockMenu menu, Block b) {
if (!BlockStorage.hasBlockInfo(b) || BlockStorage.getLocationInfo(b.getLocation(), "enabled") == null || BlockStorage.getLocationInfo(b.getLocation(), "enabled").equals(String.valueOf(false))) {
menu.replaceExistingItem(22, new CustomItem(new ItemStack(Material.GUNPOWDER), "&7Enabled: &4\u2718", "", "&e> Click to enable this Machine"));
menu.replaceExistingItem(22, new CustomItem(Material.GUNPOWDER, "&7Enabled: &4\u2718", "", "&e> Click to enable this Machine"));
menu.addMenuClickHandler(22, (p, slot, item, action) -> {
BlockStorage.addBlockInfo(b, "enabled", String.valueOf(true));
newInstance(menu, b);
@ -71,7 +71,7 @@ public class WitherAssembler extends SimpleSlimefunItem<BlockTicker> implements
});
}
else {
menu.replaceExistingItem(22, new CustomItem(new ItemStack(Material.REDSTONE), "&7Enabled: &2\u2714", "", "&e> Click to disable this Machine"));
menu.replaceExistingItem(22, new CustomItem(Material.REDSTONE, "&7Enabled: &2\u2714", "", "&e> Click to disable this Machine"));
menu.addMenuClickHandler(22, (p, slot, item, action) -> {
BlockStorage.addBlockInfo(b, "enabled", String.valueOf(false));
newInstance(menu, b);
@ -81,7 +81,7 @@ public class WitherAssembler extends SimpleSlimefunItem<BlockTicker> implements
double offset = (!BlockStorage.hasBlockInfo(b) || BlockStorage.getLocationInfo(b.getLocation(), "offset") == null) ? 3.0F : Double.valueOf(BlockStorage.getLocationInfo(b.getLocation(), "offset"));
menu.replaceExistingItem(31, new CustomItem(new ItemStack(Material.PISTON), "&7Offset: &3" + offset + " Block(s)", "", "&rLeft Click: &7+0.1", "&rRight Click: &7-0.1"));
menu.replaceExistingItem(31, new CustomItem(Material.PISTON, "&7Offset: &3" + offset + " Block(s)", "", "&rLeft Click: &7+0.1", "&rRight Click: &7-0.1"));
menu.addMenuClickHandler(31, (p, slot, item, action) -> {
double offsetv = DoubleHandler.fixDouble(Double.valueOf(BlockStorage.getLocationInfo(b.getLocation(), "offset")) + (action.isRightClicked() ? -0.1F : 0.1F));
BlockStorage.addBlockInfo(b, "offset", String.valueOf(offsetv));
@ -97,17 +97,27 @@ public class WitherAssembler extends SimpleSlimefunItem<BlockTicker> implements
@Override
public int[] getSlotsAccessedByItemTransport(ItemTransportFlow flow) {
if (flow == ItemTransportFlow.INSERT) return getInputSlots();
else return new int[0];
if (flow == ItemTransportFlow.INSERT) {
return getInputSlots();
}
else {
return new int[0];
}
}
@Override
public int[] getSlotsAccessedByItemTransport(DirtyChestMenu menu, ItemTransportFlow flow, ItemStack item) {
if (flow == ItemTransportFlow.INSERT) {
if (SlimefunUtils.isItemSimilar(item, new ItemStack(Material.SOUL_SAND), true)) return getSoulSandSlots();
else return getWitherSkullSlots();
if (flow == ItemTransportFlow.INSERT && item != null) {
if (item.getType() == Material.SOUL_SAND) {
return getSoulSandSlots();
}
if (item.getType() == Material.WITHER_SKELETON_SKULL) {
return getWitherSkullSlots();
}
}
else return new int[0];
return new int[0];
}
};
@ -121,7 +131,10 @@ public class WitherAssembler extends SimpleSlimefunItem<BlockTicker> implements
@Override
public boolean onBreak(Player p, Block b, SlimefunItem item, UnregisterReason reason) {
if (reason == UnregisterReason.EXPLODE) return false;
if (reason == UnregisterReason.EXPLODE) {
return false;
}
BlockMenu inv = BlockStorage.getInventory(b);
if (inv != null) {
@ -139,6 +152,7 @@ public class WitherAssembler extends SimpleSlimefunItem<BlockTicker> implements
}
}
}
return true;
}
});
@ -227,7 +241,7 @@ public class WitherAssembler extends SimpleSlimefunItem<BlockTicker> implements
int found = 0;
for (int slot : slots) {
if (SlimefunUtils.isItemSimilar(menu.getItemInSlot(slot), new ItemStack(resource), true)) {
if (SlimefunUtils.isItemSimilar(menu.getItemInSlot(slot), new ItemStack(resource), true, false)) {
found += menu.getItemInSlot(slot).getAmount();
if (found > required) {
@ -244,7 +258,7 @@ public class WitherAssembler extends SimpleSlimefunItem<BlockTicker> implements
int skulls = 3;
for (int slot : getSoulSandSlots()) {
if (SlimefunUtils.isItemSimilar(inv.getItemInSlot(slot), new ItemStack(Material.SOUL_SAND), true)) {
if (SlimefunUtils.isItemSimilar(inv.getItemInSlot(slot), new ItemStack(Material.SOUL_SAND), true, false)) {
int amount = inv.getItemInSlot(slot).getAmount();
if (amount >= soulsand) {
@ -259,7 +273,7 @@ public class WitherAssembler extends SimpleSlimefunItem<BlockTicker> implements
}
for (int slot : getWitherSkullSlots()) {
if (SlimefunUtils.isItemSimilar(inv.getItemInSlot(slot), new ItemStack(Material.WITHER_SKELETON_SKULL), true)) {
if (SlimefunUtils.isItemSimilar(inv.getItemInSlot(slot), new ItemStack(Material.WITHER_SKELETON_SKULL), true, false)) {
int amount = inv.getItemInSlot(slot).getAmount();
if (amount >= skulls) {

View File

@ -36,7 +36,7 @@ public abstract class OilPump extends AContainer implements RecipeDisplayItem {
public OilPump(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(category, item, recipeType, recipe);
oil = SlimefunPlugin.getRegistry().getGEOResources().get(new NamespacedKey(SlimefunPlugin.instance, "oil")).orElse(null);
oil = SlimefunPlugin.getRegistry().getGEOResources().get(new NamespacedKey(SlimefunPlugin.instance(), "oil")).orElse(null);
new BlockMenuPreset(getID(), getInventoryTitle()) {

View File

@ -96,7 +96,7 @@ public class ElevatorPlate extends SimpleSlimefunItem<BlockUseHandler> {
return;
}
CustomBookInterface book = new CustomBookInterface(SlimefunPlugin.instance);
CustomBookInterface book = new CustomBookInterface(SlimefunPlugin.instance());
ChatComponent page = null;
List<Block> floors = getFloors(b);
@ -125,7 +125,7 @@ public class ElevatorPlate extends SimpleSlimefunItem<BlockUseHandler> {
else {
line = new ChatComponent("\n" + ChatColor.GRAY.toString() + (floors.size() - i) + ". " + ChatColor.RESET + floor);
line.setHoverEvent(new HoverEvent(ChatColors.color(SlimefunPlugin.getLocalization().getMessage(p, "machines.ELEVATOR.click-to-teleport")), "", ChatColor.RESET + floor, ""));
line.setClickEvent(new ClickEvent(new NamespacedKey(SlimefunPlugin.instance, DATA_KEY + i), player -> Slimefun.runSync(() -> {
line.setClickEvent(new ClickEvent(new NamespacedKey(SlimefunPlugin.instance(), DATA_KEY + i), player -> Slimefun.runSync(() -> {
users.add(player.getUniqueId());
float yaw = player.getEyeLocation().getYaw() + 180;

View File

@ -37,7 +37,7 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
*/
public class StormStaff extends SimpleSlimefunItem<ItemUseHandler> {
private static final NamespacedKey usageKey = new NamespacedKey(SlimefunPlugin.instance, "stormstaff_usage");
private static final NamespacedKey usageKey = new NamespacedKey(SlimefunPlugin.instance(), "stormstaff_usage");
public static final int MAX_USES = 8;
public StormStaff(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {

View File

@ -19,7 +19,7 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
*/
class EnderTalisman extends Talisman {
private static final LockedCategory ENDER_TALISMANS_CATEGORY = new LockedCategory(new NamespacedKey(SlimefunPlugin.instance, "ender_talismans"), new CustomItem(SlimefunItems.ENDER_TALISMAN, "&7Talismans - &aTier II"), 3, Talisman.TALISMANS_CATEGORY.getKey());
private static final LockedCategory ENDER_TALISMANS_CATEGORY = new LockedCategory(new NamespacedKey(SlimefunPlugin.instance(), "ender_talismans"), new CustomItem(SlimefunItems.ENDER_TALISMAN, "&7Talismans - &aTier II"), 3, Talisman.TALISMANS_CATEGORY.getKey());
public EnderTalisman(Talisman parent, SlimefunItemStack item) {
super(ENDER_TALISMANS_CATEGORY, item, new ItemStack[] { SlimefunItems.ENDER_LUMP_3, null, SlimefunItems.ENDER_LUMP_3, null, parent.getItem(), null, SlimefunItems.ENDER_LUMP_3, null, SlimefunItems.ENDER_LUMP_3 }, parent.isConsumable(), parent.isEventCancelled(), parent.getMessageSuffix(), parent.getChance(), parent.getEffects());

View File

@ -31,7 +31,7 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
public class Talisman extends SlimefunItem {
protected static final Category TALISMANS_CATEGORY = new Category(new NamespacedKey(SlimefunPlugin.instance, "talismans"), new CustomItem(SlimefunItems.COMMON_TALISMAN, "&7Talismans - &aTier I"), 2);
protected static final Category TALISMANS_CATEGORY = new Category(new NamespacedKey(SlimefunPlugin.instance(), "talismans"), new CustomItem(SlimefunItems.COMMON_TALISMAN, "&7Talismans - &aTier I"), 2);
private final SlimefunItemStack enderTalisman;
@ -117,7 +117,7 @@ public class Talisman extends SlimefunItem {
protected void createEnderTalisman() {
EnderTalisman talisman = (EnderTalisman) SlimefunItem.getByItem(getEnderVariant());
Optional<Research> research = Research.getResearch(new NamespacedKey(SlimefunPlugin.instance, "ender_talismans"));
Optional<Research> research = Research.getResearch(new NamespacedKey(SlimefunPlugin.instance(), "ender_talismans"));
if (talisman != null && research.isPresent()) {
talisman.setResearch(research.get());

View File

@ -1,24 +1,32 @@
package io.github.thebusybiscuit.slimefun4.implementation.items.electric;
package io.github.thebusybiscuit.slimefun4.implementation.items.misc;
import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.slimefun4.api.events.PlayerRightClickEvent;
import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting;
import io.github.thebusybiscuit.slimefun4.core.attributes.NotPlaceable;
import io.github.thebusybiscuit.slimefun4.core.attributes.RandomMobDrop;
import io.github.thebusybiscuit.slimefun4.core.handlers.ItemUseHandler;
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SimpleSlimefunItem;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
public class BasicCircuitBoard extends SimpleSlimefunItem<ItemUseHandler> implements NotPlaceable {
public class BasicCircuitBoard extends SimpleSlimefunItem<ItemUseHandler> implements NotPlaceable, RandomMobDrop {
private final ItemSetting<Boolean> dropSetting = new ItemSetting<>("drop-from-golems", true);
private final ItemSetting<Integer> chance = new ItemSetting<>("golem-drop-chance", 75);
public BasicCircuitBoard(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(category, item, recipeType, recipe);
addItemSetting(dropSetting);
addItemSetting(chance);
}
@Override
public int getMobDropChance() {
return chance.getValue();
}
public boolean isDroppedFromGolems() {
@ -30,4 +38,4 @@ public class BasicCircuitBoard extends SimpleSlimefunItem<ItemUseHandler> implem
return PlayerRightClickEvent::cancel;
}
}
}

View File

@ -0,0 +1,35 @@
package io.github.thebusybiscuit.slimefun4.implementation.items.misc;
import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.slimefun4.implementation.items.blocks.UnplaceableBlock;
import io.github.thebusybiscuit.slimefun4.implementation.items.cargo.ReactorAccessPort;
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.reactors.NetherStarReactor;
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.reactors.NuclearReactor;
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.reactors.Reactor;
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
/**
* A {@link CoolantCell} is an {@link ItemStack} that is used to cool a {@link Reactor}.
*
* @author TheBusyBiscuit
*
* @see Reactor
* @see ReactorAccessPort
* @see NuclearReactor
* @see NetherStarReactor
*
*/
public class CoolantCell extends UnplaceableBlock {
public CoolantCell(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(category, item, recipeType, recipe);
}
public CoolantCell(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe, ItemStack recipeOutput) {
super(category, item, recipeType, recipe, recipeOutput);
}
}

View File

@ -76,7 +76,7 @@ public class AutomatedPanningMachine extends MultiBlockMachine {
}
});
queue.execute(SlimefunPlugin.instance);
queue.execute(SlimefunPlugin.instance());
}
else {
SlimefunPlugin.getLocalization().sendMessage(p, "machines.wrong-item", true);

View File

@ -81,7 +81,7 @@ public class MagicWorkbench extends BackpackCrafter {
private void startAnimation(Player p, Block b, Inventory inv, ItemStack output) {
for (int j = 0; j < 4; j++) {
int current = j;
Bukkit.getScheduler().runTaskLater(SlimefunPlugin.instance, () -> {
Bukkit.getScheduler().runTaskLater(SlimefunPlugin.instance(), () -> {
p.getWorld().playEffect(b.getLocation(), Effect.MOBSPAWNER_FLAMES, 1);
p.getWorld().playEffect(b.getLocation(), Effect.ENDER_SIGNAL, 1);

View File

@ -70,7 +70,7 @@ public class PressureChamber extends MultiBlockMachine {
for (int i = 0; i < 4; i++) {
int j = i;
Bukkit.getScheduler().runTaskLater(SlimefunPlugin.instance, () -> {
Bukkit.getScheduler().runTaskLater(SlimefunPlugin.instance(), () -> {
p.getWorld().playSound(b.getLocation(), Sound.ENTITY_TNT_PRIMED, 1, 1);
p.getWorld().playEffect(b.getRelative(BlockFace.UP).getLocation(), Effect.SMOKE, 4);
p.getWorld().playEffect(b.getRelative(BlockFace.UP).getLocation(), Effect.SMOKE, 4);

View File

@ -149,7 +149,7 @@ class ActiveMiner implements Runnable {
queue.thenRun(2, () -> setPistonState(pistons[1], false));
queue.thenRun(1, this);
queue.execute(SlimefunPlugin.instance);
queue.execute(SlimefunPlugin.instance());
}
@Override
@ -202,7 +202,7 @@ class ActiveMiner implements Runnable {
}
});
queue.execute(SlimefunPlugin.instance);
queue.execute(SlimefunPlugin.instance());
}
/**

View File

@ -38,6 +38,7 @@ class ExplosiveTool extends SimpleSlimefunItem<BlockBreakHandler> implements Not
public ExplosiveTool(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(category, item, recipeType, recipe);
addItemSetting(damageOnUse, callExplosionEvent);
}
@ -54,6 +55,7 @@ class ExplosiveTool extends SimpleSlimefunItem<BlockBreakHandler> implements Not
public boolean onBlockBreak(BlockBreakEvent e, ItemStack item, int fortune, List<ItemStack> drops) {
if (isItem(item)) {
Player p = e.getPlayer();
if (Slimefun.hasUnlocked(p, ExplosiveTool.this, true)) {
Block b = e.getBlock();
@ -61,21 +63,7 @@ class ExplosiveTool extends SimpleSlimefunItem<BlockBreakHandler> implements Not
b.getWorld().playSound(b.getLocation(), Sound.ENTITY_GENERIC_EXPLODE, 0.2F, 1F);
List<Block> blocks = findBlocks(b);
if (callExplosionEvent.getValue().booleanValue()) {
BlockExplodeEvent blockExplodeEvent = new BlockExplodeEvent(b, blocks, 0);
Bukkit.getServer().getPluginManager().callEvent(blockExplodeEvent);
if (!blockExplodeEvent.isCancelled()) {
for (Block block : blockExplodeEvent.blockList()) {
breakBlock(p, item, block, fortune, drops);
}
}
}
else {
for (Block block : blocks) {
breakBlock(p, item, block, fortune, drops);
}
}
breakBlocks(p, b, blocks, fortune, drops);
}
return true;
@ -87,6 +75,24 @@ class ExplosiveTool extends SimpleSlimefunItem<BlockBreakHandler> implements Not
};
}
private void breakBlocks(Player p, Block b, List<Block> blocks, int fortune, List<ItemStack> drops) {
if (callExplosionEvent.getValue().booleanValue()) {
BlockExplodeEvent blockExplodeEvent = new BlockExplodeEvent(b, blocks, 0);
Bukkit.getServer().getPluginManager().callEvent(blockExplodeEvent);
if (!blockExplodeEvent.isCancelled()) {
for (Block block : blockExplodeEvent.blockList()) {
breakBlock(p, item, block, fortune, drops);
}
}
}
else {
for (Block block : blocks) {
breakBlock(p, item, block, fortune, drops);
}
}
}
private List<Block> findBlocks(Block b) {
List<Block> blocks = new ArrayList<>(26);
@ -112,7 +118,7 @@ class ExplosiveTool extends SimpleSlimefunItem<BlockBreakHandler> implements Not
}
protected void breakBlock(Player p, ItemStack item, Block b, int fortune, List<ItemStack> drops) {
if (b.getType() != Material.AIR && !b.isLiquid() && !MaterialCollections.getAllUnbreakableBlocks().contains(b.getType()) && SlimefunPlugin.getProtectionManager().hasPermission(p, b.getLocation(), ProtectableAction.BREAK_BLOCK)) {
if (!b.isEmpty() && !b.isLiquid() && !MaterialCollections.getAllUnbreakableBlocks().contains(b.getType()) && SlimefunPlugin.getProtectionManager().hasPermission(p, b.getLocation(), ProtectableAction.BREAK_BLOCK)) {
SlimefunPlugin.getProtectionManager().logAction(p, b, ProtectableAction.BREAK_BLOCK);
b.getWorld().playEffect(b.getLocation(), Effect.STEP_SOUND, b.getType());

View File

@ -63,7 +63,7 @@ public class SeismicAxe extends SimpleSlimefunItem<ItemUseHandler> implements No
FallingBlock block = ground.getWorld().spawnFallingBlock(loc, ground.getBlockData());
block.setDropItem(false);
block.setVelocity(new Vector(0, 0.4 + i * 0.01, 0));
block.setMetadata("seismic_axe", new FixedMetadataValue(SlimefunPlugin.instance, "fake_block"));
block.setMetadata("seismic_axe", new FixedMetadataValue(SlimefunPlugin.instance(), "fake_block"));
}
for (Entity n : ground.getChunk().getEntities()) {

View File

@ -61,7 +61,7 @@ public class ButcherAndroidListener implements Listener {
}, 1L);
// Removing metadata to prevent memory leaks
e.getEntity().removeMetadata(METADATA_KEY, SlimefunPlugin.instance);
e.getEntity().removeMetadata(METADATA_KEY, SlimefunPlugin.instance());
}
}

View File

@ -1,7 +1,7 @@
package io.github.thebusybiscuit.slimefun4.implementation.listeners;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ThreadLocalRandom;
import org.bukkit.Material;
import org.bukkit.entity.Player;
@ -10,20 +10,17 @@ import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDeathEvent;
import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.slimefun4.core.attributes.RandomMobDrop;
import io.github.thebusybiscuit.slimefun4.core.handlers.EntityKillHandler;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.BasicCircuitBoard;
import io.github.thebusybiscuit.slimefun4.implementation.items.misc.BasicCircuitBoard;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.api.Slimefun;
public class MobDropListener implements Listener {
private final BasicCircuitBoard circuitBoard;
public MobDropListener(SlimefunPlugin plugin, BasicCircuitBoard circuitBoard) {
public MobDropListener(SlimefunPlugin plugin) {
plugin.getServer().getPluginManager().registerEvents(this, plugin);
this.circuitBoard = circuitBoard;
}
@EventHandler
@ -33,8 +30,13 @@ public class MobDropListener implements Listener {
ItemStack item = p.getInventory().getItemInMainHand();
Set<ItemStack> customDrops = SlimefunPlugin.getRegistry().getMobDrops(e.getEntityType());
if (customDrops != null && !customDrops.isEmpty()) {
addDrops(p, customDrops, e.getDrops());
for (ItemStack drop : customDrops) {
if (canDrop(p, drop)) {
e.getDrops().add(drop.clone());
}
}
}
if (item.getType() != Material.AIR) {
@ -47,15 +49,30 @@ public class MobDropListener implements Listener {
}
}
private void addDrops(Player p, Set<ItemStack> customDrops, List<ItemStack> drops) {
for (ItemStack drop : customDrops) {
if (Slimefun.hasUnlocked(p, drop, true)) {
if (circuitBoard != null && circuitBoard.isItem(drop) && !circuitBoard.isDroppedFromGolems()) {
continue;
}
private boolean canDrop(Player p, ItemStack item) {
SlimefunItem sfi = SlimefunItem.getByItem(item);
drops.add(drop.clone());
if (sfi == null) {
return true;
}
else if (Slimefun.hasUnlocked(p, sfi, true)) {
if (sfi instanceof RandomMobDrop) {
int random = ThreadLocalRandom.current().nextInt(100);
if (((RandomMobDrop) sfi).getMobDropChance() <= random) {
return false;
}
}
if (sfi instanceof BasicCircuitBoard) {
return ((BasicCircuitBoard) sfi).isDroppedFromGolems();
}
return true;
}
else {
return false;
}
}
}

View File

@ -35,7 +35,7 @@ public class SeismicAxeListener implements Listener {
if (e.getEntity().getType() == EntityType.FALLING_BLOCK && e.getEntity().hasMetadata("seismic_axe")) {
e.setCancelled(true);
e.getEntity().removeMetadata("seismic_axe", SlimefunPlugin.instance);
e.getEntity().removeMetadata("seismic_axe", SlimefunPlugin.instance());
e.getEntity().remove();
}
}

View File

@ -11,7 +11,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
class NetherIceResource implements GEOResource {
private final NamespacedKey key = new NamespacedKey(SlimefunPlugin.instance, "nether_ice");
private final NamespacedKey key = new NamespacedKey(SlimefunPlugin.instance(), "nether_ice");
@Override
public int getDefaultSupply(Environment environment, Biome biome) {

View File

@ -11,7 +11,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
class OilResource implements GEOResource {
private final NamespacedKey key = new NamespacedKey(SlimefunPlugin.instance, "oil");
private final NamespacedKey key = new NamespacedKey(SlimefunPlugin.instance(), "oil");
@Override
public int getDefaultSupply(Environment environment, Biome biome) {

View File

@ -11,7 +11,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
class SaltResource implements GEOResource {
private final NamespacedKey key = new NamespacedKey(SlimefunPlugin.instance, "salt");
private final NamespacedKey key = new NamespacedKey(SlimefunPlugin.instance(), "salt");
@Override
public int getDefaultSupply(Environment environment, Biome biome) {

View File

@ -11,7 +11,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
class UraniumResource implements GEOResource {
private final NamespacedKey key = new NamespacedKey(SlimefunPlugin.instance, "uranium");
private final NamespacedKey key = new NamespacedKey(SlimefunPlugin.instance(), "uranium");
@Override
public int getDefaultSupply(Environment envionment, Biome biome) {

View File

@ -32,35 +32,35 @@ import me.mrCookieSlime.Slimefun.Objects.Category;
class DefaultCategories {
// Standard Categories
protected final Category weapons = new Category(new NamespacedKey(SlimefunPlugin.instance, "weapons"), new CustomItem(SlimefunItems.BLADE_OF_VAMPIRES, "&7Weapons"), 1);
protected final Category tools = new Category(new NamespacedKey(SlimefunPlugin.instance, "tools"), new CustomItem(SlimefunItems.SMELTERS_PICKAXE, "&7Tools"), 1);
protected final Category usefulItems = new Category(new NamespacedKey(SlimefunPlugin.instance, "items"), new CustomItem(SlimefunItems.BACKPACK_MEDIUM, "&7Useful Items"), 1);
protected final Category basicMachines = new Category(new NamespacedKey(SlimefunPlugin.instance, "basic_machines"), new CustomItem(Material.CRAFTING_TABLE, "&7Basic Machines"), 1);
protected final Category food = new Category(new NamespacedKey(SlimefunPlugin.instance, "food"), new CustomItem(SlimefunItems.FORTUNE_COOKIE, "&7Food"), 2);
protected final Category armor = new Category(new NamespacedKey(SlimefunPlugin.instance, "armor"), new CustomItem(SlimefunItems.DAMASCUS_STEEL_CHESTPLATE, "&7Armor"), 2);
protected final Category weapons = new Category(new NamespacedKey(SlimefunPlugin.instance(), "weapons"), new CustomItem(SlimefunItems.BLADE_OF_VAMPIRES, "&7Weapons"), 1);
protected final Category tools = new Category(new NamespacedKey(SlimefunPlugin.instance(), "tools"), new CustomItem(SlimefunItems.SMELTERS_PICKAXE, "&7Tools"), 1);
protected final Category usefulItems = new Category(new NamespacedKey(SlimefunPlugin.instance(), "items"), new CustomItem(SlimefunItems.BACKPACK_MEDIUM, "&7Useful Items"), 1);
protected final Category basicMachines = new Category(new NamespacedKey(SlimefunPlugin.instance(), "basic_machines"), new CustomItem(Material.CRAFTING_TABLE, "&7Basic Machines"), 1);
protected final Category food = new Category(new NamespacedKey(SlimefunPlugin.instance(), "food"), new CustomItem(SlimefunItems.FORTUNE_COOKIE, "&7Food"), 2);
protected final Category armor = new Category(new NamespacedKey(SlimefunPlugin.instance(), "armor"), new CustomItem(SlimefunItems.DAMASCUS_STEEL_CHESTPLATE, "&7Armor"), 2);
// Magical
protected final Category magicalResources = new Category(new NamespacedKey(SlimefunPlugin.instance, "magical_items"), new CustomItem(SlimefunItems.ENDER_RUNE, "&7Magical Items"), 2);
protected final Category magicalGadgets = new Category(new NamespacedKey(SlimefunPlugin.instance, "magical_gadgets"), new CustomItem(SlimefunItems.INFUSED_ELYTRA, "&7Magical Gadgets"), 3);
protected final Category magicalArmor = new Category(new NamespacedKey(SlimefunPlugin.instance, "magical_armor"), new CustomItem(SlimefunItems.ENDER_HELMET, "&7Magical Armor"), 2);
protected final Category magicalResources = new Category(new NamespacedKey(SlimefunPlugin.instance(), "magical_items"), new CustomItem(SlimefunItems.ENDER_RUNE, "&7Magical Items"), 2);
protected final Category magicalGadgets = new Category(new NamespacedKey(SlimefunPlugin.instance(), "magical_gadgets"), new CustomItem(SlimefunItems.INFUSED_ELYTRA, "&7Magical Gadgets"), 3);
protected final Category magicalArmor = new Category(new NamespacedKey(SlimefunPlugin.instance(), "magical_armor"), new CustomItem(SlimefunItems.ENDER_HELMET, "&7Magical Armor"), 2);
// Resources and tech stuff
protected final Category misc = new Category(new NamespacedKey(SlimefunPlugin.instance, "misc"), new CustomItem(SlimefunItems.TIN_CAN, "&7Miscellaneous"), 2);
protected final Category technicalComponents = new Category(new NamespacedKey(SlimefunPlugin.instance, "tech_misc"), new CustomItem(SlimefunItems.HEATING_COIL, "&7Technical Components"), 2);
protected final Category technicalGadgets = new Category(new NamespacedKey(SlimefunPlugin.instance, "technical_gadgets"), new CustomItem(SlimefunItems.STEEL_JETPACK, "&7Technical Gadgets"), 3);
protected final Category resources = new Category(new NamespacedKey(SlimefunPlugin.instance, "resources"), new CustomItem(SlimefunItems.SYNTHETIC_SAPPHIRE, "&7Resources"), 1);
protected final Category misc = new Category(new NamespacedKey(SlimefunPlugin.instance(), "misc"), new CustomItem(SlimefunItems.TIN_CAN, "&7Miscellaneous"), 2);
protected final Category technicalComponents = new Category(new NamespacedKey(SlimefunPlugin.instance(), "tech_misc"), new CustomItem(SlimefunItems.HEATING_COIL, "&7Technical Components"), 2);
protected final Category technicalGadgets = new Category(new NamespacedKey(SlimefunPlugin.instance(), "technical_gadgets"), new CustomItem(SlimefunItems.STEEL_JETPACK, "&7Technical Gadgets"), 3);
protected final Category resources = new Category(new NamespacedKey(SlimefunPlugin.instance(), "resources"), new CustomItem(SlimefunItems.SYNTHETIC_SAPPHIRE, "&7Resources"), 1);
// Locked Categories
protected final LockedCategory electricity = new LockedCategory(new NamespacedKey(SlimefunPlugin.instance, "electricity"), new CustomItem(SlimefunItems.NUCLEAR_REACTOR, "&bEnergy and Electricity"), 4, basicMachines.getKey());
protected final LockedCategory androids = new LockedCategory(new NamespacedKey(SlimefunPlugin.instance, "androids"), new CustomItem(SlimefunItems.PROGRAMMABLE_ANDROID, "&cProgrammable Androids"), 4, basicMachines.getKey());
protected final Category cargo = new LockedCategory(new NamespacedKey(SlimefunPlugin.instance, "cargo"), new CustomItem(SlimefunItems.CARGO_MANAGER, "&cCargo Management"), 4, basicMachines.getKey());
protected final LockedCategory gps = new LockedCategory(new NamespacedKey(SlimefunPlugin.instance, "gps"), new CustomItem(SlimefunItems.GPS_TRANSMITTER, "&bGPS-based Machines"), 4, basicMachines.getKey());
protected final LockedCategory electricity = new LockedCategory(new NamespacedKey(SlimefunPlugin.instance(), "electricity"), new CustomItem(SlimefunItems.NUCLEAR_REACTOR, "&bEnergy and Electricity"), 4, basicMachines.getKey());
protected final LockedCategory androids = new LockedCategory(new NamespacedKey(SlimefunPlugin.instance(), "androids"), new CustomItem(SlimefunItems.PROGRAMMABLE_ANDROID, "&cProgrammable Androids"), 4, basicMachines.getKey());
protected final Category cargo = new LockedCategory(new NamespacedKey(SlimefunPlugin.instance(), "cargo"), new CustomItem(SlimefunItems.CARGO_MANAGER, "&cCargo Management"), 4, basicMachines.getKey());
protected final LockedCategory gps = new LockedCategory(new NamespacedKey(SlimefunPlugin.instance(), "gps"), new CustomItem(SlimefunItems.GPS_TRANSMITTER, "&bGPS-based Machines"), 4, basicMachines.getKey());
// Seasonal Categories
protected final SeasonalCategory christmas = new SeasonalCategory(new NamespacedKey(SlimefunPlugin.instance, "christmas"), Month.DECEMBER, 1, new CustomItem(SlimefunUtils.getCustomHead("215ba31cde2671b8f176de6a9ffd008035f0590d63ee240be6e8921cd2037a45"), ChatUtils.christmas("Christmas") + " &7(December only)"));
protected final SeasonalCategory valentinesDay = new SeasonalCategory(new NamespacedKey(SlimefunPlugin.instance, "valentines_day"), Month.FEBRUARY, 2, new CustomItem(SlimefunUtils.getCustomHead("55d89431d14bfef2060461b4a3565614dc51115c001fae2508e8684bc0ae6a80"), "&dValentine's Day" + " &7(14th February)"));
protected final SeasonalCategory easter = new SeasonalCategory(new NamespacedKey(SlimefunPlugin.instance, "easter"), Month.APRIL, 2, new CustomItem(HeadTexture.EASTER_EGG.getAsItemStack(), "&6Easter" + " &7(April)"));
protected final SeasonalCategory birthday = new SeasonalCategory(new NamespacedKey(SlimefunPlugin.instance, "birthday"), Month.OCTOBER, 1, new CustomItem(Material.FIREWORK_ROCKET, "&a&lTheBusyBiscuit's Birthday &7(26th October)"));
protected final SeasonalCategory halloween = new SeasonalCategory(new NamespacedKey(SlimefunPlugin.instance, "halloween"), Month.OCTOBER, 1, new CustomItem(Material.JACK_O_LANTERN, "&6&lHalloween &7(31st October)"));
protected final SeasonalCategory christmas = new SeasonalCategory(new NamespacedKey(SlimefunPlugin.instance(), "christmas"), Month.DECEMBER, 1, new CustomItem(SlimefunUtils.getCustomHead("215ba31cde2671b8f176de6a9ffd008035f0590d63ee240be6e8921cd2037a45"), ChatUtils.christmas("Christmas") + " &7(December only)"));
protected final SeasonalCategory valentinesDay = new SeasonalCategory(new NamespacedKey(SlimefunPlugin.instance(), "valentines_day"), Month.FEBRUARY, 2, new CustomItem(SlimefunUtils.getCustomHead("55d89431d14bfef2060461b4a3565614dc51115c001fae2508e8684bc0ae6a80"), "&dValentine's Day" + " &7(14th February)"));
protected final SeasonalCategory easter = new SeasonalCategory(new NamespacedKey(SlimefunPlugin.instance(), "easter"), Month.APRIL, 2, new CustomItem(HeadTexture.EASTER_EGG.getAsItemStack(), "&6Easter" + " &7(April)"));
protected final SeasonalCategory birthday = new SeasonalCategory(new NamespacedKey(SlimefunPlugin.instance(), "birthday"), Month.OCTOBER, 1, new CustomItem(Material.FIREWORK_ROCKET, "&a&lTheBusyBiscuit's Birthday &7(26th October)"));
protected final SeasonalCategory halloween = new SeasonalCategory(new NamespacedKey(SlimefunPlugin.instance(), "halloween"), Month.OCTOBER, 1, new CustomItem(Material.JACK_O_LANTERN, "&6&lHalloween &7(31st October)"));
}

View File

@ -217,9 +217,13 @@ public final class PostSetup {
}
for (SlimefunItem item : SlimefunPlugin.getRegistry().getEnabledSlimefunItems()) {
if (item instanceof AContainer && ((AContainer) item).getMachineIdentifier().equals("ELECTRIC_SMELTERY")) {
List<MachineRecipe> recipes = ((AContainer) item).getMachineRecipes();
Collections.sort(recipes, Comparator.comparingInt(recipe -> recipe == null ? 0 : -recipe.getInput().length));
if (item instanceof AContainer) {
AContainer machine = (AContainer) item;
if (machine.getMachineIdentifier().equals("ELECTRIC_SMELTERY")) {
List<MachineRecipe> recipes = machine.getMachineRecipes();
Collections.sort(recipes, Comparator.comparingInt(recipe -> recipe == null ? 0 : -recipe.getInput().length));
}
}
}
}
@ -254,8 +258,12 @@ public final class PostSetup {
private static void registerMachineRecipe(String machine, int seconds, ItemStack[] input, ItemStack[] output) {
for (SlimefunItem item : SlimefunPlugin.getRegistry().getEnabledSlimefunItems()) {
if (item instanceof AContainer && ((AContainer) item).getMachineIdentifier().equals(machine)) {
((AContainer) item).registerRecipe(seconds, input, output);
if (item instanceof AContainer) {
AContainer container = (AContainer) item;
if (container.getMachineIdentifier().equals(machine)) {
container.registerRecipe(seconds, input, output);
}
}
}
}

View File

@ -272,7 +272,7 @@ public final class ResearchSetup {
}
private static void register(String key, int id, String name, int defaultCost, ItemStack... items) {
Research research = new Research(new NamespacedKey(SlimefunPlugin.instance, key), id, name, defaultCost);
Research research = new Research(new NamespacedKey(SlimefunPlugin.instance(), key), id, name, defaultCost);
for (ItemStack item : items) {
SlimefunItem sfItem = SlimefunItem.getByItem(item);

View File

@ -57,7 +57,6 @@ import io.github.thebusybiscuit.slimefun4.implementation.items.cargo.CargoManage
import io.github.thebusybiscuit.slimefun4.implementation.items.cargo.CargoOutputNode;
import io.github.thebusybiscuit.slimefun4.implementation.items.cargo.ReactorAccessPort;
import io.github.thebusybiscuit.slimefun4.implementation.items.cargo.TrashCan;
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.BasicCircuitBoard;
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.Capacitor;
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.EnergyRegulator;
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.gadgets.JetBoots;
@ -140,6 +139,8 @@ import io.github.thebusybiscuit.slimefun4.implementation.items.medical.Medicine;
import io.github.thebusybiscuit.slimefun4.implementation.items.medical.Rag;
import io.github.thebusybiscuit.slimefun4.implementation.items.medical.Splint;
import io.github.thebusybiscuit.slimefun4.implementation.items.medical.Vitamins;
import io.github.thebusybiscuit.slimefun4.implementation.items.misc.BasicCircuitBoard;
import io.github.thebusybiscuit.slimefun4.implementation.items.misc.CoolantCell;
import io.github.thebusybiscuit.slimefun4.implementation.items.misc.OrganicFertilizer;
import io.github.thebusybiscuit.slimefun4.implementation.items.misc.OrganicFood;
import io.github.thebusybiscuit.slimefun4.implementation.items.multiblocks.ArmorForge;
@ -3042,12 +3043,13 @@ public final class SlimefunItemSetup {
}.register(plugin);
new SlimefunItem(categories.technicalComponents, SlimefunItems.REACTOR_COOLANT_CELL, RecipeType.FREEZER,
new CoolantCell(categories.technicalComponents, SlimefunItems.REACTOR_COOLANT_CELL, RecipeType.FREEZER,
new ItemStack[] {new ItemStack(Material.BLUE_ICE), null, null, null, null, null, null, null, null})
.register(plugin);
new SlimefunItem(categories.technicalComponents, SlimefunItems.NETHER_ICE_COOLANT_CELL, RecipeType.HEATED_PRESSURE_CHAMBER,
new ItemStack[] {SlimefunItems.ENRICHED_NETHER_ICE, null, null, null, null, null, null, null, null})
new CoolantCell(categories.technicalComponents, SlimefunItems.NETHER_ICE_COOLANT_CELL, RecipeType.HEATED_PRESSURE_CHAMBER,
new ItemStack[] {SlimefunItems.ENRICHED_NETHER_ICE, null, null, null, null, null, null, null, null},
new SlimefunItemStack(SlimefunItems.NETHER_ICE_COOLANT_CELL, 4))
.register(plugin);
new RadioactiveItem(categories.resources, Radioactivity.HIGH, SlimefunItems.NEPTUNIUM, RecipeType.NUCLEAR_REACTOR,

View File

@ -129,7 +129,7 @@ public class AncientAltarTask implements Runnable {
itemLock.remove(item);
item.remove();
item.removeMetadata("no_pickup", SlimefunPlugin.instance);
item.removeMetadata("no_pickup", SlimefunPlugin.instance());
}
}

View File

@ -19,11 +19,11 @@ abstract class PlayerTask implements Runnable {
}
public void schedule(long delay) {
setID(Bukkit.getScheduler().scheduleSyncDelayedTask(SlimefunPlugin.instance, this, delay));
setID(Bukkit.getScheduler().scheduleSyncDelayedTask(SlimefunPlugin.instance(), this, delay));
}
public void scheduleRepeating(long delay, long interval) {
setID(Bukkit.getScheduler().scheduleSyncRepeatingTask(SlimefunPlugin.instance, this, delay, interval));
setID(Bukkit.getScheduler().scheduleSyncRepeatingTask(SlimefunPlugin.instance(), this, delay, interval));
}
@Override

View File

@ -150,7 +150,7 @@ public class TickerTask implements Runnable {
bugs.remove(position);
BlockStorage._integrated_removeBlockInfo(l, true);
Bukkit.getScheduler().scheduleSyncDelayedTask(SlimefunPlugin.instance, () -> l.getBlock().setType(Material.AIR));
Bukkit.getScheduler().scheduleSyncDelayedTask(SlimefunPlugin.instance(), () -> l.getBlock().setType(Material.AIR));
}
else {
bugs.put(position, errors);

View File

@ -48,7 +48,7 @@ public final class ChatUtils {
}
public static void awaitInput(Player p, Consumer<String> callback) {
ChatInput.waitForPlayer(SlimefunPlugin.instance, p, callback);
ChatInput.waitForPlayer(SlimefunPlugin.instance(), p, callback);
}
/**

View File

@ -45,7 +45,7 @@ public final class SlimefunUtils {
private static final String EMERALDENCHANTS_LORE = ChatColor.YELLOW.toString() + ChatColor.YELLOW.toString() + ChatColor.GRAY.toString();
private static final String NO_PICKUP_METADATA = "no_pickup";
private static final NamespacedKey SOULBOUND_KEY = new NamespacedKey(SlimefunPlugin.instance, "soulbound");
private static final NamespacedKey SOULBOUND_KEY = new NamespacedKey(SlimefunPlugin.instance(), "soulbound");
private static final String SOULBOUND_LORE = ChatColor.GRAY + "Soulbound";
private SlimefunUtils() {}
@ -72,7 +72,7 @@ public final class SlimefunUtils {
* The context in which this {@link Item} was flagged
*/
public static void markAsNoPickup(Item item, String context) {
item.setMetadata(NO_PICKUP_METADATA, new FixedMetadataValue(SlimefunPlugin.instance, context));
item.setMetadata(NO_PICKUP_METADATA, new FixedMetadataValue(SlimefunPlugin.instance(), context));
}
/**
@ -188,7 +188,7 @@ public final class SlimefunUtils {
* @return An {@link ItemStack} with this Head texture
*/
public static ItemStack getCustomHead(String texture) {
if (SlimefunPlugin.instance == null) {
if (SlimefunPlugin.instance() == null) {
throw new PrematureCodeException("You cannot instantiate a custom head before Slimefun was loaded.");
}

View File

@ -28,34 +28,34 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
public class RecipeType implements Keyed {
public static final RecipeType MULTIBLOCK = new RecipeType(new NamespacedKey(SlimefunPlugin.instance, "multiblock"), new CustomItem(Material.BRICKS, "&bMultiBlock", "", "&a&oBuild it in the World"));
public static final RecipeType ARMOR_FORGE = new RecipeType(new NamespacedKey(SlimefunPlugin.instance, "armor_forge"), SlimefunItems.ARMOR_FORGE, "", "&a&oCraft it in an Armor Forge");
public static final RecipeType GRIND_STONE = new RecipeType(new NamespacedKey(SlimefunPlugin.instance, "grind_stone"), SlimefunItems.GRIND_STONE, "", "&a&oGrind it using the Grind Stone");
public static final RecipeType SMELTERY = new RecipeType(new NamespacedKey(SlimefunPlugin.instance, "smeltery"), SlimefunItems.SMELTERY, "", "&a&oSmelt it using a Smeltery");
public static final RecipeType ORE_CRUSHER = new RecipeType(new NamespacedKey(SlimefunPlugin.instance, "ore_crusher"), SlimefunItems.ORE_CRUSHER, "", "&a&oCrush it using the Ore Crusher");
public static final RecipeType GOLD_PAN = new RecipeType(new NamespacedKey(SlimefunPlugin.instance, "gold_pan"), SlimefunItems.GOLD_PAN, "", "&a&oUse a Gold Pan on Gravel to obtain this Item");
public static final RecipeType COMPRESSOR = new RecipeType(new NamespacedKey(SlimefunPlugin.instance, "compressor"), SlimefunItems.COMPRESSOR, "", "&a&oCompress it using the Compressor");
public static final RecipeType PRESSURE_CHAMBER = new RecipeType(new NamespacedKey(SlimefunPlugin.instance, "pressure_chamber"), SlimefunItems.PRESSURE_CHAMBER, "", "&a&oCompress it using the Pressure Chamber");
public static final RecipeType MAGIC_WORKBENCH = new RecipeType(new NamespacedKey(SlimefunPlugin.instance, "magic_workbench"), SlimefunItems.MAGIC_WORKBENCH, "", "&a&oCraft it in a Magic Workbench");
public static final RecipeType ORE_WASHER = new RecipeType(new NamespacedKey(SlimefunPlugin.instance, "ore_washer"), SlimefunItems.ORE_WASHER, "", "&a&oWash it in an Ore Washer");
public static final RecipeType ENHANCED_CRAFTING_TABLE = new RecipeType(new NamespacedKey(SlimefunPlugin.instance, "enhanced_crafting_table"), SlimefunItems.ENHANCED_CRAFTING_TABLE, "", "&a&oA regular Crafting Table cannot", "&a&ohold this massive Amount of Power...");
public static final RecipeType JUICER = new RecipeType(new NamespacedKey(SlimefunPlugin.instance, "juicer"), SlimefunItems.JUICER, "", "&a&oUsed for Juice Creation");
public static final RecipeType MULTIBLOCK = new RecipeType(new NamespacedKey(SlimefunPlugin.instance(), "multiblock"), new CustomItem(Material.BRICKS, "&bMultiBlock", "", "&a&oBuild it in the World"));
public static final RecipeType ARMOR_FORGE = new RecipeType(new NamespacedKey(SlimefunPlugin.instance(), "armor_forge"), SlimefunItems.ARMOR_FORGE, "", "&a&oCraft it in an Armor Forge");
public static final RecipeType GRIND_STONE = new RecipeType(new NamespacedKey(SlimefunPlugin.instance(), "grind_stone"), SlimefunItems.GRIND_STONE, "", "&a&oGrind it using the Grind Stone");
public static final RecipeType SMELTERY = new RecipeType(new NamespacedKey(SlimefunPlugin.instance(), "smeltery"), SlimefunItems.SMELTERY, "", "&a&oSmelt it using a Smeltery");
public static final RecipeType ORE_CRUSHER = new RecipeType(new NamespacedKey(SlimefunPlugin.instance(), "ore_crusher"), SlimefunItems.ORE_CRUSHER, "", "&a&oCrush it using the Ore Crusher");
public static final RecipeType GOLD_PAN = new RecipeType(new NamespacedKey(SlimefunPlugin.instance(), "gold_pan"), SlimefunItems.GOLD_PAN, "", "&a&oUse a Gold Pan on Gravel to obtain this Item");
public static final RecipeType COMPRESSOR = new RecipeType(new NamespacedKey(SlimefunPlugin.instance(), "compressor"), SlimefunItems.COMPRESSOR, "", "&a&oCompress it using the Compressor");
public static final RecipeType PRESSURE_CHAMBER = new RecipeType(new NamespacedKey(SlimefunPlugin.instance(), "pressure_chamber"), SlimefunItems.PRESSURE_CHAMBER, "", "&a&oCompress it using the Pressure Chamber");
public static final RecipeType MAGIC_WORKBENCH = new RecipeType(new NamespacedKey(SlimefunPlugin.instance(), "magic_workbench"), SlimefunItems.MAGIC_WORKBENCH, "", "&a&oCraft it in a Magic Workbench");
public static final RecipeType ORE_WASHER = new RecipeType(new NamespacedKey(SlimefunPlugin.instance(), "ore_washer"), SlimefunItems.ORE_WASHER, "", "&a&oWash it in an Ore Washer");
public static final RecipeType ENHANCED_CRAFTING_TABLE = new RecipeType(new NamespacedKey(SlimefunPlugin.instance(), "enhanced_crafting_table"), SlimefunItems.ENHANCED_CRAFTING_TABLE, "", "&a&oA regular Crafting Table cannot", "&a&ohold this massive Amount of Power...");
public static final RecipeType JUICER = new RecipeType(new NamespacedKey(SlimefunPlugin.instance(), "juicer"), SlimefunItems.JUICER, "", "&a&oUsed for Juice Creation");
public static final RecipeType ANCIENT_ALTAR = new RecipeType(new NamespacedKey(SlimefunPlugin.instance, "ancient_altar"), SlimefunItems.ANCIENT_ALTAR, (recipe, output) -> {
public static final RecipeType ANCIENT_ALTAR = new RecipeType(new NamespacedKey(SlimefunPlugin.instance(), "ancient_altar"), SlimefunItems.ANCIENT_ALTAR, (recipe, output) -> {
AltarRecipe altarRecipe = new AltarRecipe(Arrays.asList(recipe), output);
SlimefunPlugin.getAncientAltarListener().getRecipes().add(altarRecipe);
});
public static final RecipeType MOB_DROP = new RecipeType(new NamespacedKey(SlimefunPlugin.instance, "mob_drop"), new CustomItem(Material.IRON_SWORD, "&bMob Drop"), RecipeType::registerMobDrop, "", "&rKill the specified Mob to obtain this Item");
public static final RecipeType MOB_DROP = new RecipeType(new NamespacedKey(SlimefunPlugin.instance(), "mob_drop"), new CustomItem(Material.IRON_SWORD, "&bMob Drop"), RecipeType::registerMobDrop, "", "&rKill the specified Mob to obtain this Item");
public static final RecipeType HEATED_PRESSURE_CHAMBER = new RecipeType(new NamespacedKey(SlimefunPlugin.instance, "heated_pressure_chamber"), SlimefunItems.HEATED_PRESSURE_CHAMBER);
public static final RecipeType FOOD_FABRICATOR = new RecipeType(new NamespacedKey(SlimefunPlugin.instance, "food_fabricator"), SlimefunItems.FOOD_FABRICATOR);
public static final RecipeType FOOD_COMPOSTER = new RecipeType(new NamespacedKey(SlimefunPlugin.instance, "food_composter"), SlimefunItems.FOOD_COMPOSTER);
public static final RecipeType FREEZER = new RecipeType(new NamespacedKey(SlimefunPlugin.instance, "freezer"), SlimefunItems.FREEZER);
public static final RecipeType REFINERY = new RecipeType(new NamespacedKey(SlimefunPlugin.instance, "refinery"), SlimefunItems.REFINERY);
public static final RecipeType HEATED_PRESSURE_CHAMBER = new RecipeType(new NamespacedKey(SlimefunPlugin.instance(), "heated_pressure_chamber"), SlimefunItems.HEATED_PRESSURE_CHAMBER);
public static final RecipeType FOOD_FABRICATOR = new RecipeType(new NamespacedKey(SlimefunPlugin.instance(), "food_fabricator"), SlimefunItems.FOOD_FABRICATOR);
public static final RecipeType FOOD_COMPOSTER = new RecipeType(new NamespacedKey(SlimefunPlugin.instance(), "food_composter"), SlimefunItems.FOOD_COMPOSTER);
public static final RecipeType FREEZER = new RecipeType(new NamespacedKey(SlimefunPlugin.instance(), "freezer"), SlimefunItems.FREEZER);
public static final RecipeType REFINERY = new RecipeType(new NamespacedKey(SlimefunPlugin.instance(), "refinery"), SlimefunItems.REFINERY);
public static final RecipeType GEO_MINER = new RecipeType(new NamespacedKey(SlimefunPlugin.instance, "geo_miner"), SlimefunItems.GEO_MINER);
public static final RecipeType NUCLEAR_REACTOR = new RecipeType(new NamespacedKey(SlimefunPlugin.instance, "nuclear_reactor"), SlimefunItems.NUCLEAR_REACTOR);
public static final RecipeType GEO_MINER = new RecipeType(new NamespacedKey(SlimefunPlugin.instance(), "geo_miner"), SlimefunItems.GEO_MINER);
public static final RecipeType NUCLEAR_REACTOR = new RecipeType(new NamespacedKey(SlimefunPlugin.instance(), "nuclear_reactor"), SlimefunItems.NUCLEAR_REACTOR);
public static final RecipeType NULL = new RecipeType();
@ -67,7 +67,7 @@ public class RecipeType implements Keyed {
private RecipeType() {
this.item = null;
this.machine = "";
this.key = new NamespacedKey(SlimefunPlugin.instance, "null");
this.key = new NamespacedKey(SlimefunPlugin.instance(), "null");
}
public RecipeType(ItemStack item, String machine) {
@ -75,10 +75,10 @@ public class RecipeType implements Keyed {
this.machine = machine;
if (machine.length() > 0) {
this.key = new NamespacedKey(SlimefunPlugin.instance, machine.toLowerCase(Locale.ROOT));
this.key = new NamespacedKey(SlimefunPlugin.instance(), machine.toLowerCase(Locale.ROOT));
}
else {
this.key = new NamespacedKey(SlimefunPlugin.instance, "unknown");
this.key = new NamespacedKey(SlimefunPlugin.instance(), "unknown");
}
}
@ -149,22 +149,27 @@ public class RecipeType implements Keyed {
SlimefunPlugin.getRegistry().getMobDrops().put(entity, dropping);
}
@Deprecated
public static List<ItemStack> getRecipeInputs(MultiBlockMachine machine) {
if (machine == null) return new ArrayList<>();
if (machine == null) {
return new ArrayList<>();
}
List<ItemStack[]> recipes = machine.getRecipes();
List<ItemStack> convertible = new ArrayList<>();
for (int i = 0; i < recipes.size(); i++) {
if (i % 2 == 0) convertible.add(recipes.get(i)[0]);
if (i % 2 == 0) {
convertible.add(recipes.get(i)[0]);
}
}
return convertible;
}
@Deprecated
public static List<ItemStack[]> getRecipeInputList(MultiBlockMachine machine) {
if (machine == null) return new ArrayList<>();
if (machine == null) {
return new ArrayList<>();
}
List<ItemStack[]> recipes = machine.getRecipes();
List<ItemStack[]> convertible = new ArrayList<>();
@ -190,13 +195,11 @@ public class RecipeType implements Keyed {
return convertible;
}
@Deprecated
public static ItemStack getRecipeOutput(MultiBlockMachine machine, ItemStack input) {
List<ItemStack[]> recipes = machine.getRecipes();
return recipes.get(((getRecipeInputs(machine).indexOf(input) * 2) + 1))[0].clone();
}
@Deprecated
public static ItemStack getRecipeOutputList(MultiBlockMachine machine, ItemStack[] input) {
List<ItemStack[]> recipes = machine.getRecipes();
return recipes.get((recipes.indexOf(input) + 1))[0];

View File

@ -29,7 +29,7 @@ public final class Slimefun {
private Slimefun() {}
public static Logger getLogger() {
return SlimefunPlugin.instance.getLogger();
return SlimefunPlugin.instance().getLogger();
}
/**
@ -231,11 +231,11 @@ public final class Slimefun {
return null;
}
if (SlimefunPlugin.instance == null || !SlimefunPlugin.instance.isEnabled()) {
if (SlimefunPlugin.instance() == null || !SlimefunPlugin.instance().isEnabled()) {
return null;
}
return Bukkit.getScheduler().runTask(SlimefunPlugin.instance, r);
return Bukkit.getScheduler().runTask(SlimefunPlugin.instance(), r);
}
public static BukkitTask runSync(Runnable r, long delay) {
@ -244,10 +244,10 @@ public final class Slimefun {
return null;
}
if (SlimefunPlugin.instance == null || !SlimefunPlugin.instance.isEnabled()) {
if (SlimefunPlugin.instance() == null || !SlimefunPlugin.instance().isEnabled()) {
return null;
}
return Bukkit.getScheduler().runTaskLater(SlimefunPlugin.instance, r, delay);
return Bukkit.getScheduler().runTaskLater(SlimefunPlugin.instance(), r, delay);
}
}

View File

@ -148,7 +148,7 @@ public class SlimefunItemStack extends CustomItem {
Validate.notNull(id, "The Item id must never be null!");
Validate.isTrue(id.equals(id.toUpperCase(Locale.ROOT)), "Slimefun Item Ids must be uppercase! (e.g. 'MY_ITEM_ID')");
if (SlimefunPlugin.instance == null) {
if (SlimefunPlugin.instance() == null) {
throw new PrematureCodeException("A SlimefunItemStack must never be be created before your Plugin was enabled.");
}

View File

@ -46,10 +46,6 @@ public final class ChargableBlock {
}
}
public static void setCharge(Block b, int charge) {
setCharge(b.getLocation(), charge);
}
public static void setCharge(Location l, int charge) {
if (charge < 0) {
charge = 0;
@ -62,7 +58,9 @@ public final class ChargableBlock {
}
}
BlockStorage.addBlockInfo(l, KEY, String.valueOf(charge), false);
if (charge != getCharge(l)) {
BlockStorage.addBlockInfo(l, KEY, String.valueOf(charge), false);
}
}
public static void setUnsafeCharge(Location l, int charge, boolean updateTexture) {
@ -96,15 +94,15 @@ public final class ChargableBlock {
if (availableSpace > 0 && addedCharge > 0) {
if (availableSpace > addedCharge) {
charge += addedCharge;
setCharge(l, charge);
rest = 0;
}
else {
rest = addedCharge - availableSpace;
charge = capacity;
setCharge(l, charge);
}
setCharge(l, charge);
if (SlimefunPlugin.getRegistry().getEnergyCapacitors().contains(id)) {
updateCapacitor(l, charge, capacity);
}

View File

@ -1,158 +1,163 @@
---
minecraft:
blasting:
lore:
- このアイテムの精錬に使用する
- '機械: 溶鉱炉'
name: 溶鉱炉での精錬
campfire:
lore:
- このアイテムの精錬に使用する
- '機械: 焚き火'
name: 焚き火
furnace:
lore:
- このアイテムの精錬に使用する
- '機械: かまど'
name: かまどでの精錬
shaped:
lore:
- このアイテムの作成に使用する
- '機械: 作業台'
- 並べ方は固定
name: 定形レシピ
shapeless:
lore:
- このアイテムの作成に使用する
- '機械: 作業台'
- 並べ方は自由
name: 不定形レシピ
smoking:
lore:
- このアイテムの燻製に使用する
- '機械: 燻製器'
name: 燻製器
stonecutting:
lore:
- このアイテムの作成に使用する
- '機械: 石切台'
name: 石切台
slimefun:
ancient_altar:
multiblock:
name: マルチブロック
lore:
- このアイテムの作成に使用する
- '機械: Ancient Altar'
- 詳細はAncient Altarに記載
name: Ancient Altar
armor_forge:
lore:
- このアイテムの作成に使用する
- '機械: Armor Forge'
name: Armor Forge
compressor:
lore:
- このアイテムの作成に使用する
- '機械: Compressor'
name: Compressor
- 図面通りに設置して建造する。
- クラフトではありません!
enhanced_crafting_table:
name: Enhanced Crafting Table
lore:
- このアイテムの作成に使用する
- '機械: Enhanced Crafting Table'
- 通常の作業台では不十分です!
name: Enhanced Crafting Table
food_composter:
armor_forge:
name: Armor Forge
lore:
- このアイテムの作成に使用する
- '機械: Food Composter'
name: Food Composter
food_fabricator:
lore:
- このアイテムの作成に使用する
- '機械: Food Fabricator'
name: Food Fabricator
freezer:
lore:
- このアイテムの作成に使用する
- '機械: Freezer'
name: Freezer
geo_miner:
lore:
- このアイテムの採掘に使用する
- '機械: GEO Miner'
name: GEO Miner
gold_pan:
lore:
- このアイテムの入手に使用する
- '機械: Gold Pan'
name: Gold Pan
- '機械: Armor Forge'
grind_stone:
name: Grind Stone
lore:
- このアイテムの作成に使用する
- '機械: Grind Stone'
name: Grind Stone
heated_pressure_chamber:
smeltery:
name: Smeltery
lore:
- このアイテムの作成に使用する
- '機械: Heated Pressure Chamber'
name: Heated Pressure Chamber
juicer:
lore:
- このジュースの作成に使用する
- '機械: Juicer'
name: Juicer
magic_workbench:
lore:
- このアイテムの作成に使用する
- '機械: Magic Workbench'
name: Magic Workbench
mob_drop:
lore:
- モブを倒して
- 入手するアイテム
name: モブドロップ
multiblock:
lore:
- 図面通りに設置して
- 建造する。クラフトではありません!
name: マルチブロック
nuclear_reactor:
lore:
- このアイテムを副産物として入手できる
- '機械: Nuclear Reactor'
name: Nuclear Reactor
oil_pump:
lore:
- このアイテムの収集に使用する
- '機械: Oil Pump'
name: Oil Pump
- '機械: Smeltery'
ore_crusher:
name: Ore Crusher
lore:
- このアイテムの作成に使用する
- '機械: Ore Crusher'
name: Ore Crusher
mob_drop:
name: モブドロップ
lore:
- モブを倒して
- 入手するアイテム
gold_pan:
name: Gold Pan
lore:
- このアイテムの入手に使用する
- '機械: Gold Pan'
compressor:
name: Compressor
lore:
- このアイテムの作成に使用する
- '機械: Compressor'
pressure_chamber:
name: Pressure Chamber
lore:
- このアイテムの作成に使用する
- '機械: Pressure Chamber'
ore_washer:
name: Ore Washer
lore:
- このアイテムの作成に使用する
- '機械: Ore Washer'
name: Ore Washer
juicer:
name: Juicer
lore:
- このジュースの作成に使用する
- '機械: Juicer'
magic_workbench:
name: Magic Workbench
lore:
- このアイテムの作成に使用する
- '機械: Magic Workbench'
ancient_altar:
name: Ancient Altar
lore:
- このアイテムの作成に使用する
- '機械: Ancient Altar'
- 詳細はAncient Altarに記載
heated_pressure_chamber:
name: Heated Pressure Chamber
lore:
- このアイテムの作成に使用する
- '機械: Heated Pressure Chamber'
food_fabricator:
name: Food Fabricator
lore:
- このアイテムの作成に使用する
- '機械: Food Fabricator'
food_composter:
name: Food Composter
lore:
- このアイテムの作成に使用する
- '機械: Food Composter'
freezer:
name: Freezer
lore:
- このアイテムの作成に使用する
- '機械: Freezer'
geo_miner:
name: GEO Miner
lore:
- このアイテムの採掘に使用する
- '機械: GEO Miner'
nuclear_reactor:
name: Nuclear Reactor
lore:
- このアイテムを副産物として入手できる
- '機械: Nuclear Reactor'
oil_pump:
name: Oil Pump
lore:
- このアイテムの収集に使用する
- '機械: Oil Pump'
pickaxe_of_containment:
name: Pickaxe of Containment
lore:
- このブロックを入手するには
- Pickaxe of Containmentを
- 使用してスポナーを採掘する
name: Pickaxe of Containment
pressure_chamber:
lore:
- このアイテムの作成に使用する
- '機械: Pressure Chamber'
name: Pressure Chamber
refinery:
name: Refinery
lore:
- このアイテムの作成に使用する
- '機械: Refinery'
name: Refinery
smeltery:
minecraft:
shaped:
name: 定形レシピ
lore:
- このアイテムの作成に使用する
- '機械: Smeltery'
name: Smeltery
- '機械: 作業台'
- 並べ方は固定
shapeless:
name: 不定形レシピ
lore:
- このアイテムの作成に使用する
- '機械: 作業台'
- 並べ方は自由
furnace:
name: かまどでの精錬
lore:
- このアイテムの精錬に使用する
- '機械: かまど'
blasting:
name: 溶鉱炉での精錬
lore:
- このアイテムの精錬に使用する
- '機械: 溶鉱炉'
smoking:
name: 燻製器
lore:
- このアイテムの燻製に使用する
- '機械: 燻製器'
campfire:
name: 焚き火
lore:
- このアイテムの精錬に使用する
- '機械: 焚き火'
stonecutting:
name: 石切台
lore:
- このアイテムの作成に使用する
- '機械: 石切台'
smithing:
name: 鍛冶台
lore:
- このアイテムの作成に使用する
- '機械: 鍛冶台'

View File

@ -49,7 +49,7 @@ public class TestCategories {
Category category = new Category(new NamespacedKey(plugin, "getter_test"), new CustomItem(Material.DIAMOND_AXE, "&6Testing"));
Assertions.assertEquals(3, category.getTier());
Assertions.assertEquals(new NamespacedKey(SlimefunPlugin.instance, "getter_test"), category.getKey());
Assertions.assertEquals(new NamespacedKey(SlimefunPlugin.instance(), "getter_test"), category.getKey());
Assertions.assertEquals("Testing", category.getUnlocalizedName());
Assertions.assertEquals(0, category.getItems().size());
}