mirror of
https://github.com/StarWishsama/Slimefun4.git
synced 2024-09-19 19:25:48 +00:00
Refactoring and general improvements
This commit is contained in:
parent
e0a6042619
commit
7059ad216c
@ -21,8 +21,12 @@
|
|||||||
|
|
||||||
## Release Candidate 14 (TBD)
|
## Release Candidate 14 (TBD)
|
||||||
|
|
||||||
|
#### Additions
|
||||||
|
* Added a starting sound for the Ancient Altar
|
||||||
|
|
||||||
#### Changes
|
#### Changes
|
||||||
* Coolant Cells now last twice as long
|
* Coolant Cells now last twice as long
|
||||||
|
* Small performance improvements
|
||||||
|
|
||||||
#### Fixes
|
#### Fixes
|
||||||
* Fixed #2005
|
* Fixed #2005
|
||||||
|
@ -36,7 +36,7 @@ Here is a full summary of the differences between the two different versions of
|
|||||||
| **Bug Reports** | :heavy_check_mark: | :x: |
|
| **Bug Reports** | :heavy_check_mark: | :x: |
|
||||||
| **testing before release** | :x: | :heavy_check_mark: |
|
| **testing before release** | :x: | :heavy_check_mark: |
|
||||||
| **change logs** | :x: | :memo: **[change log](https://github.com/TheBusyBiscuit/Slimefun4/blob/master/CHANGELOG.md)** |
|
| **change logs** | :x: | :memo: **[change log](https://github.com/TheBusyBiscuit/Slimefun4/blob/master/CHANGELOG.md)** |
|
||||||
| **Download link** | :package: **[download latest](https://thebusybiscuit.github.io/builds/TheBusyBiscuit/Slimefun4/master/)** | :package: **[download "stable"](https://thebusybiscuit.github.io/builds/TheBusyBiscuit/Slimefun4/stable/)** |
|
| **Download link** | :floppy_disk: **[download latest](https://thebusybiscuit.github.io/builds/TheBusyBiscuit/Slimefun4/master/)** | :floppy_disk: **[download "stable"](https://thebusybiscuit.github.io/builds/TheBusyBiscuit/Slimefun4/stable/)** |
|
||||||
|
|
||||||
**:exclamation: We wholeheartedly recommend you to use _development builds_, they are the most recent version of Slimefun and also receive the most frequent updates!**
|
**:exclamation: We wholeheartedly recommend you to use _development builds_, they are the most recent version of Slimefun and also receive the most frequent updates!**
|
||||||
<details>
|
<details>
|
||||||
|
@ -5,6 +5,7 @@ import java.util.HashSet;
|
|||||||
import java.util.Queue;
|
import java.util.Queue;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.apache.commons.lang.Validate;
|
||||||
import org.bukkit.Color;
|
import org.bukkit.Color;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Particle;
|
import org.bukkit.Particle;
|
||||||
@ -68,7 +69,18 @@ public abstract class Network {
|
|||||||
protected final Set<Location> connectorNodes = new HashSet<>();
|
protected final Set<Location> connectorNodes = new HashSet<>();
|
||||||
protected final Set<Location> terminusNodes = new HashSet<>();
|
protected final Set<Location> terminusNodes = new HashSet<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This constructs a new {@link Network} at the given {@link Location}.
|
||||||
|
*
|
||||||
|
* @param manager
|
||||||
|
* The {@link NetworkManager} instance
|
||||||
|
* @param regulator
|
||||||
|
* The {@link Location} marking the regulator of this {@link Network}.
|
||||||
|
*/
|
||||||
protected Network(NetworkManager manager, Location regulator) {
|
protected Network(NetworkManager manager, Location regulator) {
|
||||||
|
Validate.notNull(manager, "A NetworkManager must be provided");
|
||||||
|
Validate.notNull(regulator, "No regulator was specified");
|
||||||
|
|
||||||
this.manager = manager;
|
this.manager = manager;
|
||||||
this.regulator = regulator;
|
this.regulator = regulator;
|
||||||
|
|
||||||
|
@ -59,6 +59,11 @@ public class NetworkManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public <T extends Network> Optional<T> getNetworkFromLocation(Location l, Class<T> type) {
|
public <T extends Network> Optional<T> getNetworkFromLocation(Location l, Class<T> type) {
|
||||||
|
if (l == null) {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
Validate.notNull(type, "Type must not be null");
|
||||||
for (Network network : networks) {
|
for (Network network : networks) {
|
||||||
if (type.isInstance(network) && network.connectsTo(l)) {
|
if (type.isInstance(network) && network.connectsTo(l)) {
|
||||||
return Optional.of(type.cast(network));
|
return Optional.of(type.cast(network));
|
||||||
@ -69,6 +74,12 @@ public class NetworkManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public <T extends Network> List<T> getNetworksFromLocation(Location l, Class<T> type) {
|
public <T extends Network> List<T> getNetworksFromLocation(Location l, Class<T> type) {
|
||||||
|
if (l == null) {
|
||||||
|
// No networks here, if the location does not even exist
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
Validate.notNull(type, "Type must not be null");
|
||||||
List<T> list = new ArrayList<>();
|
List<T> list = new ArrayList<>();
|
||||||
|
|
||||||
for (Network network : networks) {
|
for (Network network : networks) {
|
||||||
@ -80,17 +91,38 @@ public class NetworkManager {
|
|||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void registerNetwork(Network n) {
|
/**
|
||||||
networks.add(n);
|
* This registers a given {@link Network}.
|
||||||
|
*
|
||||||
|
* @param network
|
||||||
|
* The {@link Network} to register
|
||||||
|
*/
|
||||||
|
public void registerNetwork(Network network) {
|
||||||
|
Validate.notNull(network, "Cannot register a null Network");
|
||||||
|
networks.add(network);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void unregisterNetwork(Network n) {
|
/**
|
||||||
networks.remove(n);
|
* This removes a {@link Network} from the network system.
|
||||||
|
*
|
||||||
|
* @param network
|
||||||
|
* The {@link Network} to remove
|
||||||
|
*/
|
||||||
|
public void unregisterNetwork(Network network) {
|
||||||
|
Validate.notNull(network, "Cannot unregister a null Network");
|
||||||
|
networks.remove(network);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handleAllNetworkLocationUpdate(Location l) {
|
/**
|
||||||
for (Network n : getNetworksFromLocation(l, Network.class)) {
|
* This method updates every {@link Network} found at the given {@link Location}.
|
||||||
n.markDirty(l);
|
* More precisely, {@link Network#markDirty(Location)} will be called.
|
||||||
|
*
|
||||||
|
* @param l
|
||||||
|
* The {@link Location} to update
|
||||||
|
*/
|
||||||
|
public void updateAllNetworks(Location l) {
|
||||||
|
for (Network network : getNetworksFromLocation(l, Network.class)) {
|
||||||
|
network.markDirty(l);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@ import org.bukkit.inventory.Inventory;
|
|||||||
import org.bukkit.inventory.InventoryHolder;
|
import org.bukkit.inventory.InventoryHolder;
|
||||||
import org.bukkit.inventory.ItemStack;
|
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.api.network.NetworkComponent;
|
||||||
import io.github.thebusybiscuit.slimefun4.utils.holograms.SimpleHologram;
|
import io.github.thebusybiscuit.slimefun4.utils.holograms.SimpleHologram;
|
||||||
import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config;
|
import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config;
|
||||||
@ -25,6 +26,21 @@ import me.mrCookieSlime.Slimefun.api.BlockStorage;
|
|||||||
import me.mrCookieSlime.Slimefun.api.Slimefun;
|
import me.mrCookieSlime.Slimefun.api.Slimefun;
|
||||||
import me.mrCookieSlime.Slimefun.api.inventory.DirtyChestMenu;
|
import me.mrCookieSlime.Slimefun.api.inventory.DirtyChestMenu;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link CargoNet} is a type of {@link Network} which deals with {@link ItemStack} transportation.
|
||||||
|
* It is also an extension of {@link ChestTerminalNetwork} which provides methods to deal
|
||||||
|
* with the addon ChestTerminal.
|
||||||
|
*
|
||||||
|
* @author meiamsome
|
||||||
|
* @author Poslovitch
|
||||||
|
* @author John000708
|
||||||
|
* @author BigBadE
|
||||||
|
* @author SoSeDiK
|
||||||
|
* @author TheBusyBiscuit
|
||||||
|
* @author Walshy
|
||||||
|
* @author DNx5
|
||||||
|
*
|
||||||
|
*/
|
||||||
public class CargoNet extends ChestTerminalNetwork {
|
public class CargoNet extends ChestTerminalNetwork {
|
||||||
|
|
||||||
private static final int RANGE = 5;
|
private static final int RANGE = 5;
|
||||||
@ -53,6 +69,12 @@ public class CargoNet extends ChestTerminalNetwork {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This constructs a new {@link CargoNet} at the given {@link Location}.
|
||||||
|
*
|
||||||
|
* @param l
|
||||||
|
* The {@link Location} marking the manager of this {@link Network}.
|
||||||
|
*/
|
||||||
protected CargoNet(Location l) {
|
protected CargoNet(Location l) {
|
||||||
super(l);
|
super(l);
|
||||||
}
|
}
|
||||||
@ -137,7 +159,9 @@ public class CargoNet extends ChestTerminalNetwork {
|
|||||||
Set<Location> destinations = new HashSet<>();
|
Set<Location> destinations = new HashSet<>();
|
||||||
|
|
||||||
List<Location> output16 = output.get(16);
|
List<Location> output16 = output.get(16);
|
||||||
if (output16 != null) destinations.addAll(output16);
|
if (output16 != null) {
|
||||||
|
destinations.addAll(output16);
|
||||||
|
}
|
||||||
|
|
||||||
Slimefun.runSync(() -> run(b, destinations, output));
|
Slimefun.runSync(() -> run(b, destinations, output));
|
||||||
}
|
}
|
||||||
@ -312,7 +336,7 @@ public class CargoNet extends ChestTerminalNetwork {
|
|||||||
/**
|
/**
|
||||||
* This method returns the frequency a given node is set to.
|
* 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
|
* Should there be an {@link Exception} to this method it will fall back to zero in
|
||||||
* order to protect the integrity of the {@link CargoNet}.
|
* order to preserve the integrity of the {@link CargoNet}.
|
||||||
*
|
*
|
||||||
* @param node
|
* @param node
|
||||||
* The {@link Location} of our cargo node
|
* The {@link Location} of our cargo node
|
||||||
@ -322,7 +346,7 @@ public class CargoNet extends ChestTerminalNetwork {
|
|||||||
private static int getFrequency(Location node) {
|
private static int getFrequency(Location node) {
|
||||||
try {
|
try {
|
||||||
String str = BlockStorage.getLocationInfo(node).getString("frequency");
|
String str = BlockStorage.getLocationInfo(node).getString("frequency");
|
||||||
return Integer.parseInt(str);
|
return str == null ? 0 : Integer.parseInt(str);
|
||||||
}
|
}
|
||||||
catch (Exception x) {
|
catch (Exception x) {
|
||||||
Slimefun.getLogger().log(Level.SEVERE, x, () -> "An Error occurred while parsing a Cargo Node Frequency (" + node.getWorld().getName() + " - " + node.getBlockX() + "," + node.getBlockY() + "," + +node.getBlockZ() + ")");
|
Slimefun.getLogger().log(Level.SEVERE, x, () -> "An Error occurred while parsing a Cargo Node Frequency (" + node.getWorld().getName() + " - " + node.getBlockX() + "," + node.getBlockY() + "," + +node.getBlockZ() + ")");
|
||||||
|
@ -44,6 +44,7 @@ final class CargoUtils {
|
|||||||
*/
|
*/
|
||||||
static boolean hasInventory(Block block) {
|
static boolean hasInventory(Block block) {
|
||||||
if (block == null) {
|
if (block == null) {
|
||||||
|
// No block, no inventory
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ import java.util.Iterator;
|
|||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.Queue;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
@ -53,7 +54,8 @@ abstract class ChestTerminalNetwork extends Network {
|
|||||||
protected final Set<Location> imports = new HashSet<>();
|
protected final Set<Location> imports = new HashSet<>();
|
||||||
protected final Set<Location> exports = new HashSet<>();
|
protected final Set<Location> exports = new HashSet<>();
|
||||||
|
|
||||||
private final Set<ItemRequest> itemRequests = new HashSet<>();
|
// This represents a Queue of requests to handle
|
||||||
|
private final Queue<ItemRequest> itemRequests = new LinkedList<>();
|
||||||
|
|
||||||
protected ChestTerminalNetwork(Location regulator) {
|
protected ChestTerminalNetwork(Location regulator) {
|
||||||
super(SlimefunPlugin.getNetworkManager(), regulator);
|
super(SlimefunPlugin.getNetworkManager(), regulator);
|
||||||
@ -213,7 +215,9 @@ abstract class ChestTerminalNetwork extends Network {
|
|||||||
int index = Integer.parseInt(BlockStorage.getLocationInfo(bus, "index"));
|
int index = Integer.parseInt(BlockStorage.getLocationInfo(bus, "index"));
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
if (index > (items.size() - 1)) index = 0;
|
if (index > (items.size() - 1)) {
|
||||||
|
index = 0;
|
||||||
|
}
|
||||||
|
|
||||||
BlockStorage.addBlockInfo(bus, "index", String.valueOf(index));
|
BlockStorage.addBlockInfo(bus, "index", String.valueOf(index));
|
||||||
itemRequests.add(new ItemRequest(bus, 17, items.get(index), ItemTransportFlow.WITHDRAW));
|
itemRequests.add(new ItemRequest(bus, 17, items.get(index), ItemTransportFlow.WITHDRAW));
|
||||||
@ -233,11 +237,18 @@ abstract class ChestTerminalNetwork extends Network {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method updates every terminal on the network with {@link ItemStack ItemStacks}
|
||||||
|
* found in any provider of the network.
|
||||||
|
*
|
||||||
|
* @param providers
|
||||||
|
* A {@link Set} of providers to this {@link ChestTerminalNetwork}
|
||||||
|
*/
|
||||||
protected void updateTerminals(Set<Location> providers) {
|
protected void updateTerminals(Set<Location> providers) {
|
||||||
List<ItemStackAndInteger> items = findAvailableItems(providers);
|
List<ItemStackAndInteger> items = findAvailableItems(providers);
|
||||||
|
|
||||||
for (Location l : terminals) {
|
for (Location l : terminals) {
|
||||||
BlockMenu menu = BlockStorage.getInventory(l);
|
BlockMenu terminal = BlockStorage.getInventory(l);
|
||||||
int page = Integer.parseInt(BlockStorage.getLocationInfo(l, "page"));
|
int page = Integer.parseInt(BlockStorage.getLocationInfo(l, "page"));
|
||||||
|
|
||||||
if (!items.isEmpty() && items.size() < (page - 1) * TERMINAL_SLOTS.length + 1) {
|
if (!items.isEmpty() && items.size() < (page - 1) * TERMINAL_SLOTS.length + 1) {
|
||||||
@ -247,42 +258,52 @@ abstract class ChestTerminalNetwork extends Network {
|
|||||||
|
|
||||||
for (int i = 0; i < TERMINAL_SLOTS.length; i++) {
|
for (int i = 0; i < TERMINAL_SLOTS.length; i++) {
|
||||||
int slot = TERMINAL_SLOTS[i];
|
int slot = TERMINAL_SLOTS[i];
|
||||||
|
int index = i + (TERMINAL_SLOTS.length * (page - 1));
|
||||||
if (items.size() > i + (TERMINAL_SLOTS.length * (page - 1))) {
|
updateTerminal(l, terminal, slot, index, items);
|
||||||
ItemStackAndInteger item = items.get(i + (TERMINAL_SLOTS.length * (page - 1)));
|
|
||||||
|
|
||||||
ItemStack stack = item.getItem().clone();
|
|
||||||
ItemMeta im = stack.getItemMeta();
|
|
||||||
List<String> lore = new ArrayList<>();
|
|
||||||
lore.add("");
|
|
||||||
lore.add(ChatColors.color("&7Stored Items: &r" + DoubleHandler.getFancyDouble(item.getInt())));
|
|
||||||
|
|
||||||
if (stack.getMaxStackSize() > 1) lore.add(ChatColors.color("&7<Left Click: Request 1 | Right Click: Request " + (item.getInt() > stack.getMaxStackSize() ? stack.getMaxStackSize() : item.getInt()) + ">"));
|
|
||||||
else lore.add(ChatColors.color("&7<Left Click: Request 1>"));
|
|
||||||
|
|
||||||
lore.add("");
|
|
||||||
if (im.hasLore()) {
|
|
||||||
lore.addAll(im.getLore());
|
|
||||||
}
|
|
||||||
|
|
||||||
im.setLore(lore);
|
|
||||||
stack.setItemMeta(im);
|
|
||||||
menu.replaceExistingItem(slot, stack);
|
|
||||||
menu.addMenuClickHandler(slot, (p, sl, is, action) -> {
|
|
||||||
int amount = item.getInt() > item.getItem().getMaxStackSize() ? item.getItem().getMaxStackSize() : item.getInt();
|
|
||||||
itemRequests.add(new ItemRequest(l, 44, new CustomItem(item.getItem(), action.isRightClicked() ? amount : 1), ItemTransportFlow.WITHDRAW));
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
menu.replaceExistingItem(slot, terminalPlaceholderItem);
|
|
||||||
menu.addMenuClickHandler(slot, ChestMenuUtils.getEmptyClickHandler());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateTerminal(Location l, BlockMenu terminal, int slot, int index, List<ItemStackAndInteger> items) {
|
||||||
|
if (items.size() > index) {
|
||||||
|
ItemStackAndInteger item = items.get(index);
|
||||||
|
|
||||||
|
ItemStack stack = item.getItem().clone();
|
||||||
|
ItemMeta im = stack.getItemMeta();
|
||||||
|
List<String> lore = new ArrayList<>();
|
||||||
|
lore.add("");
|
||||||
|
lore.add(ChatColors.color("&7Stored Items: &r" + DoubleHandler.getFancyDouble(item.getInt())));
|
||||||
|
|
||||||
|
if (stack.getMaxStackSize() > 1) {
|
||||||
|
int amount = item.getInt() > stack.getMaxStackSize() ? stack.getMaxStackSize() : item.getInt();
|
||||||
|
lore.add(ChatColors.color("&7<Left Click: Request 1 | Right Click: Request " + amount + ">"));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lore.add(ChatColors.color("&7<Left Click: Request 1>"));
|
||||||
|
}
|
||||||
|
|
||||||
|
lore.add("");
|
||||||
|
|
||||||
|
if (im.hasLore()) {
|
||||||
|
lore.addAll(im.getLore());
|
||||||
|
}
|
||||||
|
|
||||||
|
im.setLore(lore);
|
||||||
|
stack.setItemMeta(im);
|
||||||
|
terminal.replaceExistingItem(slot, stack);
|
||||||
|
terminal.addMenuClickHandler(slot, (p, sl, is, action) -> {
|
||||||
|
int amount = item.getInt() > item.getItem().getMaxStackSize() ? item.getItem().getMaxStackSize() : item.getInt();
|
||||||
|
itemRequests.add(new ItemRequest(l, 44, new CustomItem(item.getItem(), action.isRightClicked() ? amount : 1), ItemTransportFlow.WITHDRAW));
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
terminal.replaceExistingItem(slot, terminalPlaceholderItem);
|
||||||
|
terminal.addMenuClickHandler(slot, ChestMenuUtils.getEmptyClickHandler());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private List<ItemStackAndInteger> findAvailableItems(Set<Location> providers) {
|
private List<ItemStackAndInteger> findAvailableItems(Set<Location> providers) {
|
||||||
List<ItemStackAndInteger> items = new LinkedList<>();
|
List<ItemStackAndInteger> items = new LinkedList<>();
|
||||||
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package io.github.thebusybiscuit.slimefun4.core.networks.cargo;
|
package io.github.thebusybiscuit.slimefun4.core.networks.cargo;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
@ -35,4 +37,20 @@ class ItemRequest {
|
|||||||
return slot;
|
return slot;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(item, slot, flow, terminal);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (obj instanceof ItemRequest) {
|
||||||
|
ItemRequest request = (ItemRequest) obj;
|
||||||
|
return Objects.equals(item, request.item) && Objects.equals(terminal, request.terminal) && slot == request.slot && flow == request.flow;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -196,7 +196,9 @@ public class EnergyNet extends Network {
|
|||||||
available = 0;
|
available = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else ChargableBlock.setUnsafeCharge(source, 0, false);
|
else {
|
||||||
|
ChargableBlock.setUnsafeCharge(source, 0, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -240,7 +242,7 @@ public class EnergyNet extends Network {
|
|||||||
item.warn("This Item was marked as a 'GENERATOR' but has no 'GeneratorTicker' attached to it! This must be fixed.");
|
item.warn("This Item was marked as a 'GENERATOR' but has no 'GeneratorTicker' attached to it! This must be fixed.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Throwable t) {
|
catch (Exception | LinkageError t) {
|
||||||
exploded.add(source);
|
exploded.add(source);
|
||||||
new ErrorReport(t, source, item);
|
new ErrorReport(t, source, item);
|
||||||
}
|
}
|
||||||
|
@ -61,7 +61,7 @@ public class ThirdPartyPluginService {
|
|||||||
Class.forName("com.sk89q.worldedit.extent.Extent");
|
Class.forName("com.sk89q.worldedit.extent.Extent");
|
||||||
new WorldEditHook();
|
new WorldEditHook();
|
||||||
}
|
}
|
||||||
catch (Throwable x) {
|
catch (Exception | LinkageError x) {
|
||||||
String version = plugin.getServer().getPluginManager().getPlugin("WorldEdit").getDescription().getVersion();
|
String version = plugin.getServer().getPluginManager().getPlugin("WorldEdit").getDescription().getVersion();
|
||||||
|
|
||||||
Slimefun.getLogger().log(Level.WARNING, "Maybe consider updating WorldEdit or Slimefun?");
|
Slimefun.getLogger().log(Level.WARNING, "Maybe consider updating WorldEdit or Slimefun?");
|
||||||
|
@ -90,7 +90,10 @@ public class BookSlimefunGuide implements SlimefunGuideImplementation {
|
|||||||
@Override
|
@Override
|
||||||
public void openMainMenu(PlayerProfile profile, int page) {
|
public void openMainMenu(PlayerProfile profile, int page) {
|
||||||
Player p = profile.getPlayer();
|
Player p = profile.getPlayer();
|
||||||
if (p == null) return;
|
|
||||||
|
if (p == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
List<ChatComponent> lines = new LinkedList<>();
|
List<ChatComponent> lines = new LinkedList<>();
|
||||||
int tier = 0;
|
int tier = 0;
|
||||||
@ -143,7 +146,10 @@ public class BookSlimefunGuide implements SlimefunGuideImplementation {
|
|||||||
@Override
|
@Override
|
||||||
public void openCategory(PlayerProfile profile, Category category, int page) {
|
public void openCategory(PlayerProfile profile, Category category, int page) {
|
||||||
Player p = profile.getPlayer();
|
Player p = profile.getPlayer();
|
||||||
if (p == null) return;
|
|
||||||
|
if (p == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (category instanceof FlexCategory) {
|
if (category instanceof FlexCategory) {
|
||||||
((FlexCategory) category).open(p, profile, getLayout());
|
((FlexCategory) category).open(p, profile, getLayout());
|
||||||
|
@ -95,7 +95,10 @@ public class ChestSlimefunGuide implements SlimefunGuideImplementation {
|
|||||||
@Override
|
@Override
|
||||||
public void openMainMenu(PlayerProfile profile, int page) {
|
public void openMainMenu(PlayerProfile profile, int page) {
|
||||||
Player p = profile.getPlayer();
|
Player p = profile.getPlayer();
|
||||||
if (p == null) return;
|
|
||||||
|
if (p == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (isSurvivalMode()) {
|
if (isSurvivalMode()) {
|
||||||
profile.getGuideHistory().clear();
|
profile.getGuideHistory().clear();
|
||||||
@ -167,7 +170,10 @@ public class ChestSlimefunGuide implements SlimefunGuideImplementation {
|
|||||||
@Override
|
@Override
|
||||||
public void openCategory(PlayerProfile profile, Category category, int page) {
|
public void openCategory(PlayerProfile profile, Category category, int page) {
|
||||||
Player p = profile.getPlayer();
|
Player p = profile.getPlayer();
|
||||||
if (p == null) return;
|
|
||||||
|
if (p == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (category instanceof FlexCategory) {
|
if (category instanceof FlexCategory) {
|
||||||
((FlexCategory) category).open(p, profile, getLayout());
|
((FlexCategory) category).open(p, profile, getLayout());
|
||||||
@ -258,7 +264,7 @@ public class ChestSlimefunGuide implements SlimefunGuideImplementation {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Throwable x) {
|
catch (Exception | LinkageError x) {
|
||||||
printErrorMessage(pl, x);
|
printErrorMessage(pl, x);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -276,7 +282,10 @@ public class ChestSlimefunGuide implements SlimefunGuideImplementation {
|
|||||||
@Override
|
@Override
|
||||||
public void openSearch(PlayerProfile profile, String input, boolean addToHistory) {
|
public void openSearch(PlayerProfile profile, String input, boolean addToHistory) {
|
||||||
Player p = profile.getPlayer();
|
Player p = profile.getPlayer();
|
||||||
if (p == null) return;
|
|
||||||
|
if (p == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ChestMenu menu = new ChestMenu(SlimefunPlugin.getLocal().getMessage(p, "guide.search.inventory").replace("%item%", ChatUtils.crop(ChatColor.RESET, input)));
|
ChestMenu menu = new ChestMenu(SlimefunPlugin.getLocal().getMessage(p, "guide.search.inventory").replace("%item%", ChatUtils.crop(ChatColor.RESET, input)));
|
||||||
String searchTerm = input.toLowerCase(Locale.ROOT);
|
String searchTerm = input.toLowerCase(Locale.ROOT);
|
||||||
@ -294,7 +303,9 @@ public class ChestSlimefunGuide implements SlimefunGuideImplementation {
|
|||||||
for (SlimefunItem item : SlimefunPlugin.getRegistry().getEnabledSlimefunItems()) {
|
for (SlimefunItem item : SlimefunPlugin.getRegistry().getEnabledSlimefunItems()) {
|
||||||
String itemName = ChatColor.stripColor(item.getItemName()).toLowerCase(Locale.ROOT);
|
String itemName = ChatColor.stripColor(item.getItemName()).toLowerCase(Locale.ROOT);
|
||||||
|
|
||||||
if (index == 44) break;
|
if (index == 44) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (!itemName.isEmpty() && (itemName.equals(searchTerm) || itemName.contains(searchTerm))) {
|
if (!itemName.isEmpty() && (itemName.equals(searchTerm) || itemName.contains(searchTerm))) {
|
||||||
ItemStack itemstack = new CustomItem(item.getItem(), meta -> {
|
ItemStack itemstack = new CustomItem(item.getItem(), meta -> {
|
||||||
@ -303,6 +314,7 @@ public class ChestSlimefunGuide implements SlimefunGuideImplementation {
|
|||||||
|
|
||||||
if (category != null) {
|
if (category != null) {
|
||||||
ItemStack categoryItem = category.getItem(p);
|
ItemStack categoryItem = category.getItem(p);
|
||||||
|
|
||||||
if (categoryItem != null && categoryItem.hasItemMeta() && categoryItem.getItemMeta().hasDisplayName()) {
|
if (categoryItem != null && categoryItem.hasItemMeta() && categoryItem.getItemMeta().hasDisplayName()) {
|
||||||
lore = Arrays.asList("", ChatColor.DARK_GRAY + "\u21E8 " + ChatColor.RESET + categoryItem.getItemMeta().getDisplayName());
|
lore = Arrays.asList("", ChatColor.DARK_GRAY + "\u21E8 " + ChatColor.RESET + categoryItem.getItemMeta().getDisplayName());
|
||||||
}
|
}
|
||||||
@ -322,7 +334,7 @@ public class ChestSlimefunGuide implements SlimefunGuideImplementation {
|
|||||||
displayItem(profile, item, true);
|
displayItem(profile, item, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Throwable x) {
|
catch (Exception | LinkageError x) {
|
||||||
printErrorMessage(pl, x);
|
printErrorMessage(pl, x);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -339,9 +351,10 @@ public class ChestSlimefunGuide implements SlimefunGuideImplementation {
|
|||||||
@Override
|
@Override
|
||||||
public void displayItem(PlayerProfile profile, ItemStack item, int index, boolean addToHistory) {
|
public void displayItem(PlayerProfile profile, ItemStack item, int index, boolean addToHistory) {
|
||||||
Player p = profile.getPlayer();
|
Player p = profile.getPlayer();
|
||||||
if (p == null) return;
|
|
||||||
|
|
||||||
if (item == null || item.getType() == Material.AIR) return;
|
if (p == null || item == null || item.getType() == Material.AIR) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
SlimefunItem sfItem = SlimefunItem.getByItem(item);
|
SlimefunItem sfItem = SlimefunItem.getByItem(item);
|
||||||
|
|
||||||
@ -488,7 +501,7 @@ public class ChestSlimefunGuide implements SlimefunGuideImplementation {
|
|||||||
displayItem(profile, itemstack, 0, true);
|
displayItem(profile, itemstack, 0, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Throwable x) {
|
catch (Exception | LinkageError x) {
|
||||||
printErrorMessage(pl, x);
|
printErrorMessage(pl, x);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -530,8 +543,8 @@ public class ChestSlimefunGuide implements SlimefunGuideImplementation {
|
|||||||
menu.addItem(7, ChestMenuUtils.getSearchButton(p));
|
menu.addItem(7, ChestMenuUtils.getSearchButton(p));
|
||||||
menu.addMenuClickHandler(7, (pl, slot, item, action) -> {
|
menu.addMenuClickHandler(7, (pl, slot, item, action) -> {
|
||||||
pl.closeInventory();
|
pl.closeInventory();
|
||||||
SlimefunPlugin.getLocal().sendMessage(pl, "guide.search.message");
|
|
||||||
|
|
||||||
|
SlimefunPlugin.getLocal().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;
|
return false;
|
||||||
@ -571,7 +584,10 @@ public class ChestSlimefunGuide implements SlimefunGuideImplementation {
|
|||||||
private static ItemStack getDisplayItem(Player p, boolean isSlimefunRecipe, ItemStack item) {
|
private static ItemStack getDisplayItem(Player p, boolean isSlimefunRecipe, ItemStack item) {
|
||||||
if (isSlimefunRecipe) {
|
if (isSlimefunRecipe) {
|
||||||
SlimefunItem slimefunItem = SlimefunItem.getByItem(item);
|
SlimefunItem slimefunItem = SlimefunItem.getByItem(item);
|
||||||
if (slimefunItem == null) return item;
|
|
||||||
|
if (slimefunItem == null) {
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
String lore = Slimefun.hasPermission(p, slimefunItem, false) ? "&rNeeds to be unlocked elsewhere" : "&rNo Permission";
|
String lore = Slimefun.hasPermission(p, slimefunItem, false) ? "&rNeeds to be unlocked elsewhere" : "&rNo Permission";
|
||||||
return Slimefun.hasUnlocked(p, slimefunItem, false) ? item : new CustomItem(Material.BARRIER, ItemUtils.getItemName(item), "&4&l" + SlimefunPlugin.getLocal().getMessage(p, "guide.locked"), "", lore);
|
return Slimefun.hasUnlocked(p, slimefunItem, false) ? item : new CustomItem(Material.BARRIER, ItemUtils.getItemName(item), "&4&l" + SlimefunPlugin.getLocal().getMessage(p, "guide.locked"), "", lore);
|
||||||
@ -642,7 +658,9 @@ public class ChestSlimefunGuide implements SlimefunGuideImplementation {
|
|||||||
|
|
||||||
// We want to clone this item to avoid corrupting the original
|
// We want to clone this item to avoid corrupting the original
|
||||||
// but we wanna make sure no stupid addon creator sneaked some nulls in here
|
// but we wanna make sure no stupid addon creator sneaked some nulls in here
|
||||||
if (item != null) item = item.clone();
|
if (item != null) {
|
||||||
|
item = item.clone();
|
||||||
|
}
|
||||||
|
|
||||||
menu.replaceExistingItem(slot, item);
|
menu.replaceExistingItem(slot, item);
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ package io.github.thebusybiscuit.slimefun4.implementation.guide;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.apache.commons.lang.Validate;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.Tag;
|
import org.bukkit.Tag;
|
||||||
@ -26,25 +27,39 @@ import me.mrCookieSlime.Slimefun.SlimefunPlugin;
|
|||||||
*/
|
*/
|
||||||
class RecipeChoiceTask implements Runnable {
|
class RecipeChoiceTask implements Runnable {
|
||||||
|
|
||||||
private static final int UPDATE_INTERVAL = 15;
|
private static final int UPDATE_INTERVAL = 14;
|
||||||
|
|
||||||
private Inventory inventory;
|
private Inventory inventory;
|
||||||
private int id;
|
private int id;
|
||||||
private Map<Integer, LoopIterator<Material>> iterators = new HashMap<>();
|
private Map<Integer, LoopIterator<Material>> iterators = new HashMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This will start this task for the given {@link Inventory}.
|
||||||
|
*
|
||||||
|
* @param inv
|
||||||
|
* The {@link Inventory} to start this task for
|
||||||
|
*/
|
||||||
public void start(Inventory inv) {
|
public void start(Inventory inv) {
|
||||||
|
Validate.notNull(inv, "Inventory must not be null");
|
||||||
inventory = inv;
|
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) {
|
public void add(int slot, MaterialChoice choice) {
|
||||||
|
Validate.notNull(choice, "Cannot add a null RecipeChoice");
|
||||||
iterators.put(slot, new LoopIterator<>(choice.getChoices()));
|
iterators.put(slot, new LoopIterator<>(choice.getChoices()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void add(int slot, Tag<Material> tag) {
|
public void add(int slot, Tag<Material> tag) {
|
||||||
|
Validate.notNull(tag, "Cannot add a null Tag");
|
||||||
iterators.put(slot, new LoopIterator<>(tag.getValues()));
|
iterators.put(slot, new LoopIterator<>(tag.getValues()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method checks if there are any slots that need to be updated.
|
||||||
|
*
|
||||||
|
* @return Whether this task has nothing to do
|
||||||
|
*/
|
||||||
public boolean isEmpty() {
|
public boolean isEmpty() {
|
||||||
return iterators.isEmpty();
|
return iterators.isEmpty();
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ import java.util.Collections;
|
|||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
import org.apache.commons.lang.Validate;
|
import org.apache.commons.lang.Validate;
|
||||||
@ -30,11 +31,15 @@ public final class Script {
|
|||||||
this.config = config;
|
this.config = config;
|
||||||
this.name = config.getString("name");
|
this.name = config.getString("name");
|
||||||
this.code = config.getString("code");
|
this.code = config.getString("code");
|
||||||
|
String author = config.getString("author");
|
||||||
|
|
||||||
Validate.notNull(name);
|
Validate.notNull(name);
|
||||||
Validate.notNull(code);
|
Validate.notNull(code);
|
||||||
|
Validate.notNull(author);
|
||||||
|
Validate.notNull(config.getStringList("rating.positive"));
|
||||||
|
Validate.notNull(config.getStringList("rating.negative"));
|
||||||
|
|
||||||
OfflinePlayer player = Bukkit.getOfflinePlayer(config.getUUID("author"));
|
OfflinePlayer player = Bukkit.getOfflinePlayer(UUID.fromString(author));
|
||||||
this.author = player.getName() != null ? player.getName() : config.getString("author_name");
|
this.author = player.getName() != null ? player.getName() : config.getString("author_name");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package io.github.thebusybiscuit.slimefun4.implementation.items.armor;
|
package io.github.thebusybiscuit.slimefun4.implementation.items.armor;
|
||||||
|
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.potion.PotionEffect;
|
import org.bukkit.potion.PotionEffect;
|
||||||
|
|
||||||
@ -14,11 +15,18 @@ public class SlimefunArmorPiece extends SlimefunItem {
|
|||||||
|
|
||||||
public SlimefunArmorPiece(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe, PotionEffect[] effects) {
|
public SlimefunArmorPiece(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe, PotionEffect[] effects) {
|
||||||
super(category, item, recipeType, recipe);
|
super(category, item, recipeType, recipe);
|
||||||
this.effects = effects;
|
|
||||||
|
this.effects = effects == null ? new PotionEffect[0] : effects;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An Array of {@link PotionEffect PotionEffects} which get applied to a {@link Player} wearing
|
||||||
|
* this {@link SlimefunArmorPiece}.
|
||||||
|
*
|
||||||
|
* @return An array of effects
|
||||||
|
*/
|
||||||
public PotionEffect[] getPotionEffects() {
|
public PotionEffect[] getPotionEffects() {
|
||||||
return this.effects;
|
return effects;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -42,9 +42,9 @@ public class BlockPlacer extends SimpleSlimefunItem<BlockDispenseHandler> {
|
|||||||
@Override
|
@Override
|
||||||
public BlockDispenseHandler getItemHandler() {
|
public BlockDispenseHandler getItemHandler() {
|
||||||
return (e, dispenser, facedBlock, machine) -> {
|
return (e, dispenser, facedBlock, machine) -> {
|
||||||
// Since vanilla Dispensers can already place Shulker boxes, we simply fallback
|
|
||||||
// to the vanilla behaviour.
|
|
||||||
if (isShulkerBox(e.getItem().getType())) {
|
if (isShulkerBox(e.getItem().getType())) {
|
||||||
|
// Since vanilla Dispensers can already place Shulker boxes, we
|
||||||
|
// simply fallback to the vanilla behaviour.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,8 +61,12 @@ public abstract class OilPump extends AContainer implements RecipeDisplayItem {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int[] getSlotsAccessedByItemTransport(ItemTransportFlow flow) {
|
public int[] getSlotsAccessedByItemTransport(ItemTransportFlow flow) {
|
||||||
if (flow == ItemTransportFlow.INSERT) return getInputSlots();
|
if (flow == ItemTransportFlow.INSERT) {
|
||||||
else return getOutputSlots();
|
return getInputSlots();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return getOutputSlots();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -97,9 +101,11 @@ public abstract class OilPump extends AContainer implements RecipeDisplayItem {
|
|||||||
if (timeleft > 0) {
|
if (timeleft > 0) {
|
||||||
ChestMenuUtils.updateProgressbar(inv, 22, timeleft, processing.get(b).getTicks(), getProgressBar());
|
ChestMenuUtils.updateProgressbar(inv, 22, timeleft, processing.get(b).getTicks(), getProgressBar());
|
||||||
|
|
||||||
if (ChargableBlock.getCharge(b) < getEnergyConsumption()) return;
|
if (ChargableBlock.getCharge(b) < getEnergyConsumption()) {
|
||||||
ChargableBlock.addCharge(b, -getEnergyConsumption());
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ChargableBlock.addCharge(b, -getEnergyConsumption());
|
||||||
progress.put(b, timeleft - 1);
|
progress.put(b, timeleft - 1);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -112,7 +118,7 @@ public abstract class OilPump extends AContainer implements RecipeDisplayItem {
|
|||||||
}
|
}
|
||||||
else if (inv.fits(SlimefunItems.OIL_BUCKET, getOutputSlots())) {
|
else if (inv.fits(SlimefunItems.OIL_BUCKET, getOutputSlots())) {
|
||||||
for (int slot : getInputSlots()) {
|
for (int slot : getInputSlots()) {
|
||||||
if (SlimefunUtils.isItemSimilar(inv.getItemInSlot(slot), new ItemStack(Material.BUCKET), true)) {
|
if (SlimefunUtils.isItemSimilar(inv.getItemInSlot(slot), new ItemStack(Material.BUCKET), true, false)) {
|
||||||
OptionalInt supplies = SlimefunPlugin.getGPSNetwork().getResourceManager().getSupplies(oil, b.getWorld(), b.getX() >> 4, b.getZ() >> 4);
|
OptionalInt supplies = SlimefunPlugin.getGPSNetwork().getResourceManager().getSupplies(oil, b.getWorld(), b.getX() >> 4, b.getZ() >> 4);
|
||||||
|
|
||||||
if (supplies.isPresent() && supplies.getAsInt() > 0) {
|
if (supplies.isPresent() && supplies.getAsInt() > 0) {
|
||||||
|
@ -9,9 +9,17 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
|
|||||||
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
|
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
|
||||||
import me.mrCookieSlime.Slimefun.Objects.Category;
|
import me.mrCookieSlime.Slimefun.Objects.Category;
|
||||||
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SimpleSlimefunItem;
|
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SimpleSlimefunItem;
|
||||||
|
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
|
||||||
import me.mrCookieSlime.Slimefun.Objects.handlers.ItemUseHandler;
|
import me.mrCookieSlime.Slimefun.Objects.handlers.ItemUseHandler;
|
||||||
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link KnowledgeFlask} is a magical {@link SlimefunItem} which allows you to store
|
||||||
|
* experience levels in a bottle when you right click.
|
||||||
|
*
|
||||||
|
* @author TheBusyBiscuit
|
||||||
|
*
|
||||||
|
*/
|
||||||
public class KnowledgeFlask extends SimpleSlimefunItem<ItemUseHandler> {
|
public class KnowledgeFlask extends SimpleSlimefunItem<ItemUseHandler> {
|
||||||
|
|
||||||
public KnowledgeFlask(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe, ItemStack recipeOutput) {
|
public KnowledgeFlask(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe, ItemStack recipeOutput) {
|
||||||
|
@ -1,16 +1,15 @@
|
|||||||
package io.github.thebusybiscuit.slimefun4.implementation.items.magical;
|
package io.github.thebusybiscuit.slimefun4.implementation.items.magical;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.Optional;
|
||||||
|
|
||||||
import org.bukkit.ChatColor;
|
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Sound;
|
import org.bukkit.Sound;
|
||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.entity.Entity;
|
||||||
import org.bukkit.entity.Item;
|
import org.bukkit.entity.Item;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.player.PlayerDropItemEvent;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.inventory.meta.ItemMeta;
|
|
||||||
|
|
||||||
import io.github.thebusybiscuit.slimefun4.core.attributes.Soulbound;
|
import io.github.thebusybiscuit.slimefun4.core.attributes.Soulbound;
|
||||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
|
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
|
||||||
@ -29,6 +28,8 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
|||||||
* {@link SoulboundItem}. It is also one of the very few utilisations of {@link ItemDropHandler}.
|
* {@link SoulboundItem}. It is also one of the very few utilisations of {@link ItemDropHandler}.
|
||||||
*
|
*
|
||||||
* @author Linox
|
* @author Linox
|
||||||
|
* @author Walshy
|
||||||
|
* @author TheBusyBiscuit
|
||||||
*
|
*
|
||||||
* @see ItemDropHandler
|
* @see ItemDropHandler
|
||||||
* @see Soulbound
|
* @see Soulbound
|
||||||
@ -36,65 +37,22 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
|||||||
*/
|
*/
|
||||||
public class SoulboundRune extends SimpleSlimefunItem<ItemDropHandler> {
|
public class SoulboundRune extends SimpleSlimefunItem<ItemDropHandler> {
|
||||||
|
|
||||||
|
private static final double RANGE = 1.5;
|
||||||
|
|
||||||
public SoulboundRune(Category category, SlimefunItemStack item, RecipeType type, ItemStack[] recipe) {
|
public SoulboundRune(Category category, SlimefunItemStack item, RecipeType type, ItemStack[] recipe) {
|
||||||
super(category, item, type, recipe);
|
super(category, item, type, recipe);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ItemDropHandler getItemHandler() {
|
public ItemDropHandler getItemHandler() {
|
||||||
return (e, p, droppedItem) -> {
|
return (e, p, item) -> {
|
||||||
ItemStack item = droppedItem.getItemStack();
|
if (isItem(item.getItemStack())) {
|
||||||
|
|
||||||
if (isItem(item)) {
|
|
||||||
|
|
||||||
if (!Slimefun.hasUnlocked(p, SlimefunItems.SOULBOUND_RUNE, true)) {
|
if (!Slimefun.hasUnlocked(p, SlimefunItems.SOULBOUND_RUNE, true)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Slimefun.runSync(() -> {
|
Slimefun.runSync(() -> activate(p, e, item), 20L);
|
||||||
// Being sure the entity is still valid and not picked up or whatsoever.
|
|
||||||
if (!droppedItem.isValid()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Location l = droppedItem.getLocation();
|
|
||||||
Collection<Entity> entites = l.getWorld().getNearbyEntities(l, 1.5, 1.5, 1.5, this::findCompatibleItem);
|
|
||||||
|
|
||||||
if (entites.isEmpty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Entity entity = entites.stream().findFirst().get();
|
|
||||||
ItemStack target = ((Item) entity).getItemStack();
|
|
||||||
Item targetItem = (Item) entity;
|
|
||||||
|
|
||||||
SlimefunUtils.setSoulbound(target, true);
|
|
||||||
|
|
||||||
if (target.getAmount() == 1) {
|
|
||||||
e.setCancelled(true);
|
|
||||||
|
|
||||||
// This lightning is just an effect, it deals no damage.
|
|
||||||
l.getWorld().strikeLightningEffect(l);
|
|
||||||
|
|
||||||
Slimefun.runSync(() -> {
|
|
||||||
// Being sure entities are still valid and not picked up or whatsoever.
|
|
||||||
if (droppedItem.isValid() && targetItem.isValid() && target.getAmount() == 1) {
|
|
||||||
|
|
||||||
l.getWorld().createExplosion(l, 0.0F);
|
|
||||||
l.getWorld().playSound(l, Sound.ENTITY_GENERIC_EXPLODE, 0.3F, 1F);
|
|
||||||
|
|
||||||
targetItem.remove();
|
|
||||||
droppedItem.remove();
|
|
||||||
l.getWorld().dropItemNaturally(l, target);
|
|
||||||
|
|
||||||
SlimefunPlugin.getLocal().sendMessage(p, "messages.soulbound-rune.success", true);
|
|
||||||
}
|
|
||||||
}, 10L);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
SlimefunPlugin.getLocal().sendMessage(p, "messages.soulbound-rune.fail", true);
|
|
||||||
}
|
|
||||||
}, 20L);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -102,20 +60,47 @@ public class SoulboundRune extends SimpleSlimefunItem<ItemDropHandler> {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private void activate(Player p, PlayerDropItemEvent e, Item item) {
|
||||||
* This method applies the {@link Soulbound} effect onto a given {@link ItemStack}.
|
// Being sure the entity is still valid and not picked up or whatsoever.
|
||||||
*
|
if (!item.isValid()) {
|
||||||
* @param item
|
return;
|
||||||
* The {@link ItemStack} to apply this effect to
|
}
|
||||||
*/
|
|
||||||
public void apply(ItemStack item) {
|
|
||||||
// Should rather use PersistentData here
|
|
||||||
ItemMeta meta = item.getItemMeta();
|
|
||||||
List<String> lore = meta.hasLore() ? meta.getLore() : new ArrayList<>();
|
|
||||||
lore.add(ChatColor.GRAY + "Soulbound");
|
|
||||||
|
|
||||||
meta.setLore(lore);
|
Location l = item.getLocation();
|
||||||
item.setItemMeta(meta);
|
Collection<Entity> entites = l.getWorld().getNearbyEntities(l, RANGE, RANGE, RANGE, this::findCompatibleItem);
|
||||||
|
Optional<Entity> optional = entites.stream().findFirst();
|
||||||
|
|
||||||
|
if (optional.isPresent()) {
|
||||||
|
Item entity = (Item) optional.get();
|
||||||
|
ItemStack target = entity.getItemStack();
|
||||||
|
|
||||||
|
SlimefunUtils.setSoulbound(target, true);
|
||||||
|
|
||||||
|
if (target.getAmount() == 1) {
|
||||||
|
e.setCancelled(true);
|
||||||
|
|
||||||
|
// This lightning is just an effect, it deals no damage.
|
||||||
|
l.getWorld().strikeLightningEffect(l);
|
||||||
|
|
||||||
|
Slimefun.runSync(() -> {
|
||||||
|
// Being sure entities are still valid and not picked up or whatsoever.
|
||||||
|
if (item.isValid() && entity.isValid() && target.getAmount() == 1) {
|
||||||
|
|
||||||
|
l.getWorld().createExplosion(l, 0);
|
||||||
|
l.getWorld().playSound(l, Sound.ENTITY_GENERIC_EXPLODE, 0.3F, 1);
|
||||||
|
|
||||||
|
entity.remove();
|
||||||
|
item.remove();
|
||||||
|
l.getWorld().dropItemNaturally(l, target);
|
||||||
|
|
||||||
|
SlimefunPlugin.getLocal().sendMessage(p, "messages.soulbound-rune.success", true);
|
||||||
|
}
|
||||||
|
}, 10L);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
SlimefunPlugin.getLocal().sendMessage(p, "messages.soulbound-rune.fail", true);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean findCompatibleItem(Entity n) {
|
private boolean findCompatibleItem(Entity n) {
|
||||||
|
@ -31,13 +31,14 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
|||||||
* Unlike the other Staves, it has a limited amount of uses.
|
* Unlike the other Staves, it has a limited amount of uses.
|
||||||
*
|
*
|
||||||
* @author Linox
|
* @author Linox
|
||||||
|
* @author Walshy
|
||||||
|
* @author TheBusyBiscuit
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class StormStaff extends SimpleSlimefunItem<ItemUseHandler> {
|
public class StormStaff extends SimpleSlimefunItem<ItemUseHandler> {
|
||||||
|
|
||||||
public static final int MAX_USES = 8;
|
|
||||||
|
|
||||||
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) {
|
public StormStaff(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
||||||
super(category, item, recipeType, recipe, getCraftedOutput());
|
super(category, item, recipeType, recipe, getCraftedOutput());
|
||||||
@ -58,63 +59,62 @@ public class StormStaff extends SimpleSlimefunItem<ItemUseHandler> {
|
|||||||
@Override
|
@Override
|
||||||
public ItemUseHandler getItemHandler() {
|
public ItemUseHandler getItemHandler() {
|
||||||
return e -> {
|
return e -> {
|
||||||
|
Player p = e.getPlayer();
|
||||||
ItemStack item = e.getItem();
|
ItemStack item = e.getItem();
|
||||||
|
|
||||||
if (!item.hasItemMeta()) return;
|
if (p.getFoodLevel() >= 4 || p.getGameMode() == GameMode.CREATIVE) {
|
||||||
ItemMeta itemMeta = item.getItemMeta();
|
// Get a target block with max. 30 blocks of distance
|
||||||
if (!itemMeta.hasLore()) return;
|
Location loc = p.getTargetBlock(null, 30).getLocation();
|
||||||
List<String> itemLore = itemMeta.getLore();
|
|
||||||
|
|
||||||
ItemStack sfItem = getItem();
|
if (loc.getWorld() != null && loc.getChunk().isLoaded()) {
|
||||||
ItemMeta sfItemMeta = sfItem.getItemMeta();
|
if (loc.getWorld().getPVP() && SlimefunPlugin.getProtectionManager().hasPermission(p, loc, ProtectableAction.PVP)) {
|
||||||
List<String> sfItemLore = sfItemMeta.getLore();
|
e.cancel();
|
||||||
|
useItem(p, item, loc);
|
||||||
Player p = e.getPlayer();
|
}
|
||||||
|
else {
|
||||||
// Index 1 and 3 in SlimefunItems.STAFF_STORM has lores with words and stuff so we check for them.
|
SlimefunPlugin.getLocal().sendMessage(p, "messages.no-pvp", true);
|
||||||
if (itemLore.size() < 6 && itemLore.get(1).equals(sfItemLore.get(1)) && itemLore.get(3).equals(sfItemLore.get(3))) {
|
|
||||||
if (p.getFoodLevel() >= 4 || p.getGameMode() == GameMode.CREATIVE) {
|
|
||||||
// Get a target block with max. 30 blocks of distance
|
|
||||||
Location loc = p.getTargetBlock(null, 30).getLocation();
|
|
||||||
|
|
||||||
if (loc.getWorld() != null && loc.getChunk().isLoaded()) {
|
|
||||||
if (loc.getWorld().getPVP() && SlimefunPlugin.getProtectionManager().hasPermission(p, loc, ProtectableAction.PVP)) {
|
|
||||||
loc.getWorld().strikeLightning(loc);
|
|
||||||
|
|
||||||
if (p.getInventory().getItemInMainHand().getType() != Material.SHEARS && p.getGameMode() != GameMode.CREATIVE) {
|
|
||||||
FoodLevelChangeEvent event = new FoodLevelChangeEvent(p, p.getFoodLevel() - 4);
|
|
||||||
Bukkit.getPluginManager().callEvent(event);
|
|
||||||
p.setFoodLevel(event.getFoodLevel());
|
|
||||||
}
|
|
||||||
|
|
||||||
int currentUses = itemMeta.getPersistentDataContainer().getOrDefault(usageKey, PersistentDataType.INTEGER, MAX_USES);
|
|
||||||
|
|
||||||
e.cancel();
|
|
||||||
if (currentUses == 1) {
|
|
||||||
p.playSound(p.getLocation(), Sound.ENTITY_ITEM_BREAK, 1, 1);
|
|
||||||
item.setAmount(0);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
currentUses--;
|
|
||||||
itemMeta.getPersistentDataContainer().set(usageKey, PersistentDataType.INTEGER, currentUses);
|
|
||||||
itemLore.set(4, ChatColors.color("&e" + currentUses + ' ' + (currentUses > 1 ? "Uses" : "Use") + " &7left"));
|
|
||||||
itemMeta.setLore(itemLore);
|
|
||||||
item.setItemMeta(itemMeta);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
SlimefunPlugin.getLocal().sendMessage(p, "messages.no-pvp", true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
}
|
||||||
SlimefunPlugin.getLocal().sendMessage(p, "messages.hungry", true);
|
else {
|
||||||
}
|
SlimefunPlugin.getLocal().sendMessage(p, "messages.hungry", true);
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void useItem(Player p, ItemStack item, Location loc) {
|
||||||
|
loc.getWorld().strikeLightning(loc);
|
||||||
|
|
||||||
|
if (p.getInventory().getItemInMainHand().getType() == Material.SHEARS) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p.getGameMode() != GameMode.CREATIVE) {
|
||||||
|
FoodLevelChangeEvent event = new FoodLevelChangeEvent(p, p.getFoodLevel() - 4);
|
||||||
|
Bukkit.getPluginManager().callEvent(event);
|
||||||
|
|
||||||
|
if (!event.isCancelled()) {
|
||||||
|
p.setFoodLevel(event.getFoodLevel());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemMeta meta = item.getItemMeta();
|
||||||
|
int usesLeft = meta.getPersistentDataContainer().getOrDefault(usageKey, PersistentDataType.INTEGER, MAX_USES);
|
||||||
|
|
||||||
|
if (usesLeft == 1) {
|
||||||
|
p.playSound(p.getLocation(), Sound.ENTITY_ITEM_BREAK, 1, 1);
|
||||||
|
item.setAmount(0);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
usesLeft--;
|
||||||
|
meta.getPersistentDataContainer().set(usageKey, PersistentDataType.INTEGER, usesLeft);
|
||||||
|
|
||||||
|
List<String> lore = meta.getLore();
|
||||||
|
lore.set(4, ChatColors.color("&e" + usesLeft + ' ' + (usesLeft > 1 ? "Uses" : "Use") + " &7left"));
|
||||||
|
meta.setLore(lore);
|
||||||
|
|
||||||
|
item.setItemMeta(meta);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,9 @@ abstract class AbstractSmeltery extends MultiBlockMachine {
|
|||||||
if (outputInv != null) {
|
if (outputInv != null) {
|
||||||
craft(p, b, inv, inputs.get(i), output, outputInv);
|
craft(p, b, inv, inputs.get(i), output, outputInv);
|
||||||
}
|
}
|
||||||
else SlimefunPlugin.getLocal().sendMessage(p, "machines.full-inventory", true);
|
else {
|
||||||
|
SlimefunPlugin.getLocal().sendMessage(p, "machines.full-inventory", true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -2,7 +2,6 @@ package io.github.thebusybiscuit.slimefun4.implementation.items.multiblocks;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.Sound;
|
import org.bukkit.Sound;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
@ -49,8 +48,11 @@ public class ArmorForge extends MultiBlockMachine {
|
|||||||
if (outputInv != null) {
|
if (outputInv != null) {
|
||||||
craft(p, output, inv, outputInv);
|
craft(p, output, inv, outputInv);
|
||||||
}
|
}
|
||||||
else SlimefunPlugin.getLocal().sendMessage(p, "machines.full-inventory", true);
|
else {
|
||||||
|
SlimefunPlugin.getLocal().sendMessage(p, "machines.full-inventory", true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -71,6 +73,7 @@ public class ArmorForge extends MultiBlockMachine {
|
|||||||
private void craft(Player p, ItemStack output, Inventory inv, Inventory outputInv) {
|
private void craft(Player p, ItemStack output, Inventory inv, Inventory outputInv) {
|
||||||
for (int j = 0; j < 9; j++) {
|
for (int j = 0; j < 9; j++) {
|
||||||
ItemStack item = inv.getContents()[j];
|
ItemStack item = inv.getContents()[j];
|
||||||
|
|
||||||
if (item != null && item.getType() != Material.AIR) {
|
if (item != null && item.getType() != Material.AIR) {
|
||||||
ItemUtils.consumeItem(item, true);
|
ItemUtils.consumeItem(item, true);
|
||||||
}
|
}
|
||||||
@ -79,7 +82,7 @@ public class ArmorForge extends MultiBlockMachine {
|
|||||||
for (int j = 0; j < 4; j++) {
|
for (int j = 0; j < 4; j++) {
|
||||||
int current = j;
|
int current = j;
|
||||||
|
|
||||||
Bukkit.getScheduler().runTaskLater(SlimefunPlugin.instance, () -> {
|
Slimefun.runSync(() -> {
|
||||||
if (current < 3) {
|
if (current < 3) {
|
||||||
p.getWorld().playSound(p.getLocation(), Sound.BLOCK_ANVIL_USE, 1F, 2F);
|
p.getWorld().playSound(p.getLocation(), Sound.BLOCK_ANVIL_USE, 1F, 2F);
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,6 @@ package io.github.thebusybiscuit.slimefun4.implementation.items.multiblocks;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.Sound;
|
import org.bukkit.Sound;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
@ -20,6 +19,7 @@ import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
|
|||||||
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
|
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
|
||||||
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
|
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
|
||||||
import me.mrCookieSlime.Slimefun.Objects.Category;
|
import me.mrCookieSlime.Slimefun.Objects.Category;
|
||||||
|
import me.mrCookieSlime.Slimefun.api.Slimefun;
|
||||||
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
||||||
|
|
||||||
public class Compressor extends MultiBlockMachine {
|
public class Compressor extends MultiBlockMachine {
|
||||||
@ -75,7 +75,7 @@ public class Compressor extends MultiBlockMachine {
|
|||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
int j = i;
|
int j = i;
|
||||||
|
|
||||||
Bukkit.getScheduler().runTaskLater(SlimefunPlugin.instance, () -> {
|
Slimefun.runSync(() -> {
|
||||||
if (j < 3) {
|
if (j < 3) {
|
||||||
p.getWorld().playSound(p.getLocation(), j == 1 ? Sound.BLOCK_PISTON_CONTRACT : Sound.BLOCK_PISTON_EXTEND, 1F, j == 0 ? 1F : 2F);
|
p.getWorld().playSound(p.getLocation(), j == 1 ? Sound.BLOCK_PISTON_CONTRACT : Sound.BLOCK_PISTON_EXTEND, 1F, j == 0 ? 1F : 2F);
|
||||||
}
|
}
|
||||||
|
@ -36,6 +36,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.items.altar.AncientAlta
|
|||||||
import io.github.thebusybiscuit.slimefun4.implementation.items.altar.AncientPedestal;
|
import io.github.thebusybiscuit.slimefun4.implementation.items.altar.AncientPedestal;
|
||||||
import io.github.thebusybiscuit.slimefun4.implementation.tasks.AncientAltarTask;
|
import io.github.thebusybiscuit.slimefun4.implementation.tasks.AncientAltarTask;
|
||||||
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
|
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
|
||||||
|
import io.github.thebusybiscuit.slimefun4.utils.itemstack.ItemStackWrapper;
|
||||||
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
|
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
|
||||||
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
|
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
|
||||||
import me.mrCookieSlime.Slimefun.api.BlockStorage;
|
import me.mrCookieSlime.Slimefun.api.BlockStorage;
|
||||||
@ -108,8 +109,8 @@ public class AncientAltarListener implements Listener {
|
|||||||
e.cancel();
|
e.cancel();
|
||||||
usePedestal(b, e.getPlayer());
|
usePedestal(b, e.getPlayer());
|
||||||
}
|
}
|
||||||
else if (id.equals("ANCIENT_ALTAR")) {
|
else if (id.equals(SlimefunItems.ANCIENT_ALTAR.getItemId())) {
|
||||||
if (!Slimefun.hasUnlocked(e.getPlayer(), SlimefunItems.ANCIENT_ALTAR, true) || altarsInUse.contains(b.getLocation())) {
|
if (!Slimefun.hasUnlocked(e.getPlayer(), SlimefunItems.ANCIENT_ALTAR.getItem(), true) || altarsInUse.contains(b.getLocation())) {
|
||||||
e.cancel();
|
e.cancel();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -175,9 +176,9 @@ public class AncientAltarListener implements Listener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemStack result = getRecipeOutput(catalyst, input);
|
Optional<ItemStack> result = getRecipeOutput(catalyst, input);
|
||||||
if (result != null) {
|
if (result.isPresent()) {
|
||||||
if (Slimefun.hasUnlocked(p, result, true)) {
|
if (Slimefun.hasUnlocked(p, result.get(), true)) {
|
||||||
List<ItemStack> consumed = new ArrayList<>();
|
List<ItemStack> consumed = new ArrayList<>();
|
||||||
consumed.add(catalyst);
|
consumed.add(catalyst);
|
||||||
|
|
||||||
@ -185,7 +186,8 @@ public class AncientAltarListener implements Listener {
|
|||||||
ItemUtils.consumeItem(p.getInventory().getItemInMainHand(), false);
|
ItemUtils.consumeItem(p.getInventory().getItemInMainHand(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
Slimefun.runSync(new AncientAltarTask(b, altar.getSpeed(), result, pedestals, consumed, p), 10L);
|
b.getWorld().playSound(b.getLocation(), Sound.ENTITY_ILLUSIONER_PREPARE_MIRROR, 1, 1);
|
||||||
|
Slimefun.runSync(new AncientAltarTask(b, altar.getSpeed(), result.get(), pedestals, consumed, p), 10L);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
altars.remove(b);
|
altars.remove(b);
|
||||||
@ -325,25 +327,30 @@ public class AncientAltarListener implements Listener {
|
|||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ItemStack getRecipeOutput(ItemStack catalyst, List<ItemStack> input) {
|
public Optional<ItemStack> getRecipeOutput(ItemStack catalyst, List<ItemStack> input) {
|
||||||
if (input.size() != 8) return null;
|
if (input.size() != 8) {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
if (SlimefunUtils.isItemSimilar(catalyst, SlimefunItems.BROKEN_SPAWNER, false)) {
|
ItemStackWrapper wrapper = new ItemStackWrapper(catalyst);
|
||||||
if (checkRecipe(SlimefunItems.BROKEN_SPAWNER, input) == null) {
|
List<ItemStackWrapper> items = ItemStackWrapper.wrapList(input);
|
||||||
return null;
|
|
||||||
|
if (SlimefunUtils.isItemSimilar(wrapper, SlimefunItems.BROKEN_SPAWNER, false)) {
|
||||||
|
if (!checkRecipe(SlimefunItems.BROKEN_SPAWNER, items).isPresent()) {
|
||||||
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemStack spawner = SlimefunItems.REPAIRED_SPAWNER.clone();
|
ItemStack spawner = SlimefunItems.REPAIRED_SPAWNER.clone();
|
||||||
ItemMeta im = spawner.getItemMeta();
|
ItemMeta im = spawner.getItemMeta();
|
||||||
im.setLore(Arrays.asList(catalyst.getItemMeta().getLore().get(0)));
|
im.setLore(Arrays.asList(wrapper.getItemMeta().getLore().get(0)));
|
||||||
spawner.setItemMeta(im);
|
spawner.setItemMeta(im);
|
||||||
return spawner;
|
return Optional.of(spawner);
|
||||||
}
|
}
|
||||||
|
|
||||||
return checkRecipe(catalyst, input);
|
return checkRecipe(wrapper, items);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ItemStack checkRecipe(ItemStack catalyst, List<ItemStack> items) {
|
private Optional<ItemStack> checkRecipe(ItemStack catalyst, List<ItemStackWrapper> items) {
|
||||||
for (AltarRecipe recipe : altarRecipes) {
|
for (AltarRecipe recipe : altarRecipes) {
|
||||||
if (SlimefunUtils.isItemSimilar(catalyst, recipe.getCatalyst(), true)) {
|
if (SlimefunUtils.isItemSimilar(catalyst, recipe.getCatalyst(), true)) {
|
||||||
for (int i = 0; i < 8; i++) {
|
for (int i = 0; i < 8; i++) {
|
||||||
@ -353,7 +360,7 @@ public class AncientAltarListener implements Listener {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (j == 7) {
|
else if (j == 7) {
|
||||||
return recipe.getOutput();
|
return Optional.of(recipe.getOutput());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -361,7 +368,7 @@ public class AncientAltarListener implements Listener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -31,18 +31,21 @@ import me.mrCookieSlime.Slimefun.api.Slimefun;
|
|||||||
*/
|
*/
|
||||||
public class ButcherAndroidListener implements Listener {
|
public class ButcherAndroidListener implements Listener {
|
||||||
|
|
||||||
|
private static final String METADATA_KEY = "android_killer";
|
||||||
|
|
||||||
public ButcherAndroidListener(SlimefunPlugin plugin) {
|
public ButcherAndroidListener(SlimefunPlugin plugin) {
|
||||||
plugin.getServer().getPluginManager().registerEvents(this, plugin);
|
plugin.getServer().getPluginManager().registerEvents(this, plugin);
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST)
|
@EventHandler(priority = EventPriority.HIGHEST)
|
||||||
public void onDeath(EntityDeathEvent e) {
|
public void onDeath(EntityDeathEvent e) {
|
||||||
if (e.getEntity().hasMetadata("android_killer")) {
|
if (e.getEntity().hasMetadata(METADATA_KEY)) {
|
||||||
AndroidInstance obj = (AndroidInstance) e.getEntity().getMetadata("android_killer").get(0).value();
|
AndroidInstance obj = (AndroidInstance) e.getEntity().getMetadata(METADATA_KEY).get(0).value();
|
||||||
|
|
||||||
Slimefun.runSync(() -> {
|
Slimefun.runSync(() -> {
|
||||||
List<ItemStack> items = new ArrayList<>();
|
List<ItemStack> items = new ArrayList<>();
|
||||||
|
|
||||||
|
// Collect any nearby dropped items
|
||||||
for (Entity n : e.getEntity().getNearbyEntities(0.5D, 0.5D, 0.5D)) {
|
for (Entity n : e.getEntity().getNearbyEntities(0.5D, 0.5D, 0.5D)) {
|
||||||
if (n instanceof Item && n.isValid() && !SlimefunUtils.hasNoPickupFlag((Item) n)) {
|
if (n instanceof Item && n.isValid() && !SlimefunUtils.hasNoPickupFlag((Item) n)) {
|
||||||
items.add(((Item) n).getItemStack());
|
items.add(((Item) n).getItemStack());
|
||||||
@ -56,19 +59,30 @@ public class ButcherAndroidListener implements Listener {
|
|||||||
ExperienceOrb exp = (ExperienceOrb) e.getEntity().getWorld().spawnEntity(e.getEntity().getLocation(), EntityType.EXPERIENCE_ORB);
|
ExperienceOrb exp = (ExperienceOrb) e.getEntity().getWorld().spawnEntity(e.getEntity().getLocation(), EntityType.EXPERIENCE_ORB);
|
||||||
exp.setExperience(1 + ThreadLocalRandom.current().nextInt(6));
|
exp.setExperience(1 + ThreadLocalRandom.current().nextInt(6));
|
||||||
}, 1L);
|
}, 1L);
|
||||||
e.getEntity().removeMetadata("android_killer", SlimefunPlugin.instance);
|
|
||||||
|
// Removing metadata to prevent memory leaks
|
||||||
|
e.getEntity().removeMetadata(METADATA_KEY, SlimefunPlugin.instance);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addExtraDrops(List<ItemStack> items, EntityType entityType) {
|
/**
|
||||||
|
* Some items are not dropped by default. Wither Skeleton Skulls but for some weird reason
|
||||||
|
* even Blaze rods...
|
||||||
|
*
|
||||||
|
* @param drops
|
||||||
|
* The {@link List} of item drops
|
||||||
|
* @param entityType
|
||||||
|
* The {@link EntityType} of the killed entity
|
||||||
|
*/
|
||||||
|
private void addExtraDrops(List<ItemStack> drops, EntityType entityType) {
|
||||||
Random random = ThreadLocalRandom.current();
|
Random random = ThreadLocalRandom.current();
|
||||||
|
|
||||||
if (entityType == EntityType.WITHER_SKELETON && random.nextInt(250) < 2) {
|
if (entityType == EntityType.WITHER_SKELETON && random.nextInt(250) < 2) {
|
||||||
items.add(new ItemStack(Material.WITHER_SKELETON_SKULL));
|
drops.add(new ItemStack(Material.WITHER_SKELETON_SKULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entityType == EntityType.BLAZE) {
|
if (entityType == EntityType.BLAZE) {
|
||||||
items.add(new ItemStack(Material.BLAZE_ROD, 1 + random.nextInt(1)));
|
drops.add(new ItemStack(Material.BLAZE_ROD, 1 + random.nextInt(1)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,11 +50,7 @@ public class CoolerListener implements Listener {
|
|||||||
for (ItemStack item : p.getInventory().getContents()) {
|
for (ItemStack item : p.getInventory().getContents()) {
|
||||||
if (cooler.isItem(item)) {
|
if (cooler.isItem(item)) {
|
||||||
if (Slimefun.hasUnlocked(p, cooler, true)) {
|
if (Slimefun.hasUnlocked(p, cooler, true)) {
|
||||||
PlayerProfile.getBackpack(item, backpack -> {
|
takeJuiceFromCooler(p, item);
|
||||||
if (backpack != null) {
|
|
||||||
Slimefun.runSync(() -> consumeJuice(p, backpack));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return;
|
return;
|
||||||
@ -64,6 +60,23 @@ public class CoolerListener implements Listener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This takes a {@link Juice} from the given {@link Cooler} and consumes it in order
|
||||||
|
* to restore hunger for the given {@link Player}.
|
||||||
|
*
|
||||||
|
* @param p
|
||||||
|
* The {@link Player}
|
||||||
|
* @param cooler
|
||||||
|
* The {@link Cooler} {@link ItemStack} to take the {@link Juice} from
|
||||||
|
*/
|
||||||
|
private void takeJuiceFromCooler(Player p, ItemStack cooler) {
|
||||||
|
PlayerProfile.getBackpack(cooler, backpack -> {
|
||||||
|
if (backpack != null) {
|
||||||
|
Slimefun.runSync(() -> consumeJuice(p, backpack));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private boolean consumeJuice(Player p, PlayerBackpack backpack) {
|
private boolean consumeJuice(Player p, PlayerBackpack backpack) {
|
||||||
Inventory inv = backpack.getInventory();
|
Inventory inv = backpack.getInventory();
|
||||||
int slot = -1;
|
int slot = -1;
|
||||||
|
@ -33,7 +33,7 @@ public class MobDropListener implements Listener {
|
|||||||
if (customDrops != null && !customDrops.isEmpty()) {
|
if (customDrops != null && !customDrops.isEmpty()) {
|
||||||
for (ItemStack drop : customDrops) {
|
for (ItemStack drop : customDrops) {
|
||||||
if (Slimefun.hasUnlocked(p, drop, true)) {
|
if (Slimefun.hasUnlocked(p, drop, true)) {
|
||||||
if (SlimefunUtils.isItemSimilar(drop, SlimefunItems.BASIC_CIRCUIT_BOARD, true) && !((BasicCircuitBoard) SlimefunItem.getByID("BASIC_CIRCUIT_BOARD")).isDroppedFromGolems()) {
|
if (SlimefunUtils.isItemSimilar(drop, SlimefunItems.BASIC_CIRCUIT_BOARD, true) && !((BasicCircuitBoard) SlimefunItems.BASIC_CIRCUIT_BOARD.getItem()).isDroppedFromGolems()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,11 +30,11 @@ public class NetworkListener implements Listener {
|
|||||||
|
|
||||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||||
public void onBlockBreak(BlockBreakEvent e) {
|
public void onBlockBreak(BlockBreakEvent e) {
|
||||||
manager.handleAllNetworkLocationUpdate(e.getBlock().getLocation());
|
manager.updateAllNetworks(e.getBlock().getLocation());
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||||
public void onBlockPlace(BlockPlaceEvent e) {
|
public void onBlockPlace(BlockPlaceEvent e) {
|
||||||
manager.handleAllNetworkLocationUpdate(e.getBlock().getLocation());
|
manager.updateAllNetworks(e.getBlock().getLocation());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -112,13 +112,16 @@ public class SlimefunBootsListener implements Listener {
|
|||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onTrample(PlayerInteractEvent e) {
|
public void onTrample(PlayerInteractEvent e) {
|
||||||
if (e.getAction() != Action.PHYSICAL) return;
|
if (e.getAction() == Action.PHYSICAL) {
|
||||||
if (e.getClickedBlock() == null) return;
|
Block b = e.getClickedBlock();
|
||||||
if (e.getClickedBlock().getType() != Material.FARMLAND) return;
|
|
||||||
|
|
||||||
ItemStack boots = e.getPlayer().getInventory().getBoots();
|
if (b != null && b.getType() == Material.FARMLAND) {
|
||||||
if (SlimefunUtils.isItemSimilar(boots, SlimefunItems.FARMER_SHOES, true) && Slimefun.hasUnlocked(e.getPlayer(), boots, true)) {
|
ItemStack boots = e.getPlayer().getInventory().getBoots();
|
||||||
e.setCancelled(true);
|
|
||||||
|
if (SlimefunUtils.isItemSimilar(boots, SlimefunItems.FARMER_SHOES, true) && Slimefun.hasUnlocked(e.getPlayer(), boots, true)) {
|
||||||
|
e.setCancelled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,64 +47,11 @@ public class SlimefunItemListener implements Listener {
|
|||||||
boolean itemUsed = e.getHand() == EquipmentSlot.OFF_HAND;
|
boolean itemUsed = e.getHand() == EquipmentSlot.OFF_HAND;
|
||||||
|
|
||||||
if (event.useItem() != Result.DENY) {
|
if (event.useItem() != Result.DENY) {
|
||||||
Optional<SlimefunItem> optional = event.getSlimefunItem();
|
rightClickItem(e, event, itemUsed);
|
||||||
|
|
||||||
if (optional.isPresent()) {
|
|
||||||
if (Slimefun.hasUnlocked(e.getPlayer(), optional.get(), true)) {
|
|
||||||
itemUsed = optional.get().callItemHandler(ItemUseHandler.class, handler -> handler.onRightClick(event));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
event.setUseItem(Result.DENY);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!itemUsed && event.useBlock() != Result.DENY) {
|
if (!itemUsed && event.useBlock() != Result.DENY && !rightClickBlock(e, event)) {
|
||||||
Optional<SlimefunItem> optional = event.getSlimefunBlock();
|
return;
|
||||||
|
|
||||||
if (optional.isPresent()) {
|
|
||||||
if (!Slimefun.hasUnlocked(e.getPlayer(), optional.get(), true)) {
|
|
||||||
e.setCancelled(true);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean interactable = optional.get().callItemHandler(BlockUseHandler.class, handler -> handler.onRightClick(event));
|
|
||||||
|
|
||||||
if (!interactable) {
|
|
||||||
String id = optional.get().getID();
|
|
||||||
Player p = e.getPlayer();
|
|
||||||
|
|
||||||
if (BlockMenuPreset.isInventory(id)) {
|
|
||||||
|
|
||||||
if (!p.isSneaking() || Material.AIR == event.getItem().getType()) {
|
|
||||||
e.setCancelled(true);
|
|
||||||
|
|
||||||
if (BlockStorage.hasUniversalInventory(id)) {
|
|
||||||
UniversalBlockMenu menu = BlockStorage.getUniversalInventory(id);
|
|
||||||
|
|
||||||
if (menu.canOpen(e.getClickedBlock(), p)) {
|
|
||||||
menu.open(p);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
SlimefunPlugin.getLocal().sendMessage(p, "inventory.no-access", true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (BlockStorage.getStorage(e.getClickedBlock().getWorld()).hasInventory(e.getClickedBlock().getLocation())) {
|
|
||||||
BlockMenu menu = BlockStorage.getInventory(e.getClickedBlock().getLocation());
|
|
||||||
|
|
||||||
if (menu.canOpen(e.getClickedBlock(), p)) {
|
|
||||||
menu.open(p);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
SlimefunPlugin.getLocal().sendMessage(p, "inventory.no-access", true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e.useInteractedBlock() != Result.DENY) {
|
if (e.useInteractedBlock() != Result.DENY) {
|
||||||
@ -117,6 +64,73 @@ public class SlimefunItemListener implements Listener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean rightClickItem(PlayerInteractEvent e, PlayerRightClickEvent event, boolean defaultValue) {
|
||||||
|
Optional<SlimefunItem> optional = event.getSlimefunItem();
|
||||||
|
|
||||||
|
if (optional.isPresent()) {
|
||||||
|
if (Slimefun.hasUnlocked(e.getPlayer(), optional.get(), true)) {
|
||||||
|
return optional.get().callItemHandler(ItemUseHandler.class, handler -> handler.onRightClick(event));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
event.setUseItem(Result.DENY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean rightClickBlock(PlayerInteractEvent e, PlayerRightClickEvent event) {
|
||||||
|
Optional<SlimefunItem> optional = event.getSlimefunBlock();
|
||||||
|
|
||||||
|
if (optional.isPresent()) {
|
||||||
|
if (!Slimefun.hasUnlocked(e.getPlayer(), optional.get(), true)) {
|
||||||
|
e.setCancelled(true);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean interactable = optional.get().callItemHandler(BlockUseHandler.class, handler -> handler.onRightClick(event));
|
||||||
|
|
||||||
|
if (!interactable) {
|
||||||
|
String id = optional.get().getID();
|
||||||
|
Player p = e.getPlayer();
|
||||||
|
|
||||||
|
if (BlockMenuPreset.isInventory(id)) {
|
||||||
|
openInventory(p, id, e, event);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void openInventory(Player p, String id, PlayerInteractEvent e, PlayerRightClickEvent event) {
|
||||||
|
if (!p.isSneaking() || Material.AIR == event.getItem().getType()) {
|
||||||
|
e.setCancelled(true);
|
||||||
|
|
||||||
|
if (BlockStorage.hasUniversalInventory(id)) {
|
||||||
|
UniversalBlockMenu menu = BlockStorage.getUniversalInventory(id);
|
||||||
|
|
||||||
|
if (menu.canOpen(e.getClickedBlock(), p)) {
|
||||||
|
menu.open(p);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
SlimefunPlugin.getLocal().sendMessage(p, "inventory.no-access", true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (BlockStorage.getStorage(e.getClickedBlock().getWorld()).hasInventory(e.getClickedBlock().getLocation())) {
|
||||||
|
BlockMenu menu = BlockStorage.getInventory(e.getClickedBlock().getLocation());
|
||||||
|
|
||||||
|
if (menu.canOpen(e.getClickedBlock(), p)) {
|
||||||
|
menu.open(p);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
SlimefunPlugin.getLocal().sendMessage(p, "inventory.no-access", true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onItemDrop(PlayerDropItemEvent e) {
|
public void onItemDrop(PlayerDropItemEvent e) {
|
||||||
for (ItemHandler handler : SlimefunItem.getPublicItemHandlers(ItemDropHandler.class)) {
|
for (ItemHandler handler : SlimefunItem.getPublicItemHandlers(ItemDropHandler.class)) {
|
||||||
|
@ -10,6 +10,7 @@ import org.bukkit.event.Listener;
|
|||||||
import org.bukkit.event.block.Action;
|
import org.bukkit.event.block.Action;
|
||||||
import org.bukkit.event.player.PlayerInteractEvent;
|
import org.bukkit.event.player.PlayerInteractEvent;
|
||||||
|
|
||||||
|
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
|
||||||
import io.github.thebusybiscuit.slimefun4.implementation.items.gps.ElevatorPlate;
|
import io.github.thebusybiscuit.slimefun4.implementation.items.gps.ElevatorPlate;
|
||||||
import io.github.thebusybiscuit.slimefun4.implementation.items.gps.Teleporter;
|
import io.github.thebusybiscuit.slimefun4.implementation.items.gps.Teleporter;
|
||||||
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
|
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
|
||||||
@ -26,12 +27,16 @@ public class TeleporterListener implements Listener {
|
|||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
public void onPressurePlateEnter(PlayerInteractEvent e) {
|
public void onPressurePlateEnter(PlayerInteractEvent e) {
|
||||||
if (e.getAction() != Action.PHYSICAL || e.getClickedBlock() == null) return;
|
if (e.getAction() != Action.PHYSICAL || e.getClickedBlock() == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
String id = BlockStorage.checkID(e.getClickedBlock());
|
String id = BlockStorage.checkID(e.getClickedBlock());
|
||||||
if (id == null) return;
|
if (id == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (id.equals("GPS_ACTIVATION_DEVICE_SHARED") || (id.equals("GPS_ACTIVATION_DEVICE_PERSONAL") && BlockStorage.getLocationInfo(e.getClickedBlock().getLocation(), "owner").equals(e.getPlayer().getUniqueId().toString()))) {
|
if (isTeleporterPad(id, e.getClickedBlock(), e.getPlayer().getUniqueId())) {
|
||||||
SlimefunItem teleporter = BlockStorage.check(e.getClickedBlock().getRelative(BlockFace.DOWN));
|
SlimefunItem teleporter = BlockStorage.check(e.getClickedBlock().getRelative(BlockFace.DOWN));
|
||||||
|
|
||||||
if (teleporter instanceof Teleporter && checkForPylons(e.getClickedBlock().getRelative(BlockFace.DOWN))) {
|
if (teleporter instanceof Teleporter && checkForPylons(e.getClickedBlock().getRelative(BlockFace.DOWN))) {
|
||||||
@ -40,14 +45,18 @@ public class TeleporterListener implements Listener {
|
|||||||
SlimefunPlugin.getGPSNetwork().getTeleportationManager().openTeleporterGUI(e.getPlayer(), owner, block, SlimefunPlugin.getGPSNetwork().getNetworkComplexity(owner));
|
SlimefunPlugin.getGPSNetwork().getTeleportationManager().openTeleporterGUI(e.getPlayer(), owner, block, SlimefunPlugin.getGPSNetwork().getNetworkComplexity(owner));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (id.equals("ELEVATOR_PLATE")) {
|
else if (id.equals(SlimefunItems.ELEVATOR_PLATE.getItemId())) {
|
||||||
((ElevatorPlate) SlimefunItem.getByID("ELEVATOR_PLATE")).open(e.getPlayer(), e.getClickedBlock());
|
((ElevatorPlate) SlimefunItems.ELEVATOR_PLATE.getItem()).open(e.getPlayer(), e.getClickedBlock());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isTeleporterPad(String id, Block b, UUID uuid) {
|
||||||
|
return id.equals(SlimefunItems.GPS_ACTIVATION_DEVICE_SHARED.getItemId()) || (id.equals(SlimefunItems.GPS_ACTIVATION_DEVICE_PERSONAL.getItemId()) && BlockStorage.getLocationInfo(b.getLocation(), "owner").equals(uuid.toString()));
|
||||||
|
}
|
||||||
|
|
||||||
private boolean checkForPylons(Block teleporter) {
|
private boolean checkForPylons(Block teleporter) {
|
||||||
for (BlockFace face : faces) {
|
for (BlockFace face : faces) {
|
||||||
if (!BlockStorage.check(teleporter.getRelative(face), "GPS_TELEPORTER_PYLON")) {
|
if (!BlockStorage.check(teleporter.getRelative(face), SlimefunItems.GPS_TELEPORTER_PYLON.getItemId())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -354,7 +354,7 @@ public class TickerTask implements Runnable {
|
|||||||
try {
|
try {
|
||||||
run();
|
run();
|
||||||
}
|
}
|
||||||
catch (Throwable x) {
|
catch (Exception | LinkageError x) {
|
||||||
plugin.getLogger().log(Level.SEVERE, x, () -> "An Exception was caught while ticking the Block Tickers Task for Slimefun v" + SlimefunPlugin.getVersion());
|
plugin.getLogger().log(Level.SEVERE, x, () -> "An Exception was caught while ticking the Block Tickers Task for Slimefun v" + SlimefunPlugin.getVersion());
|
||||||
abortTick();
|
abortTick();
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
package io.github.thebusybiscuit.slimefun4.utils.itemstack;
|
package io.github.thebusybiscuit.slimefun4.utils.itemstack;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.commons.lang.Validate;
|
import org.apache.commons.lang.Validate;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.enchantments.Enchantment;
|
import org.bukkit.enchantments.Enchantment;
|
||||||
@ -116,4 +119,28 @@ public final class ItemStackWrapper extends ItemStack {
|
|||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This creates an {@link ItemStackWrapper} {@link List} from a given {@link ItemStack} {@link List} *
|
||||||
|
*
|
||||||
|
* @param items
|
||||||
|
* The {@link List} of {@link ItemStack ItemStacks} to transform
|
||||||
|
*
|
||||||
|
* @return An {@link ItemStackWrapper} array
|
||||||
|
*/
|
||||||
|
public static List<ItemStackWrapper> wrapList(List<ItemStack> items) {
|
||||||
|
Validate.notNull(items, "The list must not be null!");
|
||||||
|
List<ItemStackWrapper> list = new ArrayList<>(items.size());
|
||||||
|
|
||||||
|
for (ItemStack item : items) {
|
||||||
|
if (item != null) {
|
||||||
|
list.add(new ItemStackWrapper(item));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
list.add(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -711,7 +711,7 @@ public class SlimefunItem implements Placeable {
|
|||||||
try {
|
try {
|
||||||
callable.accept(c.cast(handler.get()));
|
callable.accept(c.cast(handler.get()));
|
||||||
}
|
}
|
||||||
catch (Throwable x) {
|
catch (Exception | LinkageError x) {
|
||||||
error("Could not pass \"" + c.getSimpleName() + "\" for " + toString(), x);
|
error("Could not pass \"" + c.getSimpleName() + "\" for " + toString(), x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -449,7 +449,7 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon {
|
|||||||
try {
|
try {
|
||||||
SlimefunItemSetup.setup(this);
|
SlimefunItemSetup.setup(this);
|
||||||
}
|
}
|
||||||
catch (Throwable x) {
|
catch (Exception | LinkageError x) {
|
||||||
getLogger().log(Level.SEVERE, x, () -> "An Error occured while initializing SlimefunItems for Slimefun " + getVersion());
|
getLogger().log(Level.SEVERE, x, () -> "An Error occured while initializing SlimefunItems for Slimefun " + getVersion());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -458,7 +458,7 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon {
|
|||||||
try {
|
try {
|
||||||
ResearchSetup.setupResearches();
|
ResearchSetup.setupResearches();
|
||||||
}
|
}
|
||||||
catch (Throwable x) {
|
catch (Exception | LinkageError x) {
|
||||||
getLogger().log(Level.SEVERE, x, () -> "An Error occured while initializing Slimefun Researches for Slimefun " + getVersion());
|
getLogger().log(Level.SEVERE, x, () -> "An Error occured while initializing Slimefun Researches for Slimefun " + getVersion());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,9 +18,11 @@ import me.mrCookieSlime.Slimefun.Objects.Research;
|
|||||||
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
|
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides a few convenience methods.
|
* Provides a few static convenience methods.
|
||||||
*
|
*
|
||||||
* @since 4.0
|
* @author TheBusyBiscuit
|
||||||
|
* @author Walshy
|
||||||
|
* @author Poslovitch
|
||||||
*/
|
*/
|
||||||
public final class Slimefun {
|
public final class Slimefun {
|
||||||
|
|
||||||
|
@ -172,7 +172,8 @@ public class SlimefunItemStack extends CustomItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the {@link SlimefunItem} associated for this {@link SlimefunItemStack}. Null if no item is found.
|
* Gets the {@link SlimefunItem} associated for this {@link SlimefunItemStack}.
|
||||||
|
* Null if no item is found.
|
||||||
*
|
*
|
||||||
* @return The {@link SlimefunItem} for this {@link SlimefunItemStack}, null if not found.
|
* @return The {@link SlimefunItem} for this {@link SlimefunItemStack}, null if not found.
|
||||||
*/
|
*/
|
||||||
@ -180,6 +181,25 @@ public class SlimefunItemStack extends CustomItem {
|
|||||||
return SlimefunItem.getByID(id);
|
return SlimefunItem.getByID(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method returns the associated {@link SlimefunItem} and casts it to the provided
|
||||||
|
* {@link Class}.
|
||||||
|
*
|
||||||
|
* If no item was found or the found {@link SlimefunItem} is not of the requested type,
|
||||||
|
* the method will return null.
|
||||||
|
*
|
||||||
|
* @param <T>
|
||||||
|
* The type of {@link SlimefunItem} to cast this to
|
||||||
|
* @param type
|
||||||
|
* The {@link Class} of the target {@link SlimefunItem}
|
||||||
|
*
|
||||||
|
* @return The {@link SlimefunItem} this {@link SlimefunItem} represents, casted to the given type
|
||||||
|
*/
|
||||||
|
public <T extends SlimefunItem> T getItem(Class<T> type) {
|
||||||
|
SlimefunItem item = getItem();
|
||||||
|
return type.isInstance(item) ? type.cast(item) : null;
|
||||||
|
}
|
||||||
|
|
||||||
public ImmutableItemMeta getImmutableMeta() {
|
public ImmutableItemMeta getImmutableMeta() {
|
||||||
return immutableMeta;
|
return immutableMeta;
|
||||||
}
|
}
|
||||||
|
@ -195,7 +195,7 @@ public abstract class BlockMenuPreset extends ChestMenu {
|
|||||||
try {
|
try {
|
||||||
newInstance(menu, l.getBlock());
|
newInstance(menu, l.getBlock());
|
||||||
}
|
}
|
||||||
catch (Throwable x) {
|
catch (Exception | LinkageError x) {
|
||||||
getSlimefunItem().error("An eror occured while trying to create a BlockMenu", x);
|
getSlimefunItem().error("An eror occured while trying to create a BlockMenu", x);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -2,6 +2,7 @@ package me.mrCookieSlime.Slimefun.api.inventory;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import org.bukkit.Material;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.entity.HumanEntity;
|
import org.bukkit.entity.HumanEntity;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
@ -10,6 +11,7 @@ import org.bukkit.inventory.ItemStack;
|
|||||||
import io.github.thebusybiscuit.cscorelib2.inventory.InvUtils;
|
import io.github.thebusybiscuit.cscorelib2.inventory.InvUtils;
|
||||||
import io.github.thebusybiscuit.cscorelib2.inventory.ItemUtils;
|
import io.github.thebusybiscuit.cscorelib2.inventory.ItemUtils;
|
||||||
import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
|
import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
|
||||||
|
import io.github.thebusybiscuit.slimefun4.utils.itemstack.ItemStackWrapper;
|
||||||
import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu;
|
import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu;
|
||||||
|
|
||||||
public class DirtyChestMenu extends ChestMenu {
|
public class DirtyChestMenu extends ChestMenu {
|
||||||
@ -65,16 +67,23 @@ public class DirtyChestMenu extends ChestMenu {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean fits(ItemStack item, int... slots) {
|
public boolean fits(ItemStack item, int... slots) {
|
||||||
return InvUtils.fits(toInventory(), item, slots);
|
return InvUtils.fits(toInventory(), new ItemStackWrapper(item), slots);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ItemStack pushItem(ItemStack item, int... slots) {
|
public ItemStack pushItem(ItemStack item, int... slots) {
|
||||||
|
if (item == null || item.getType() == Material.AIR) {
|
||||||
|
throw new IllegalArgumentException("Cannot push null or AIR");
|
||||||
|
}
|
||||||
|
|
||||||
int amount = item.getAmount();
|
int amount = item.getAmount();
|
||||||
|
|
||||||
for (int slot : slots) {
|
for (int slot : slots) {
|
||||||
if (amount <= 0) break;
|
if (amount <= 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
ItemStack stack = getItemInSlot(slot);
|
ItemStack stack = getItemInSlot(slot);
|
||||||
|
|
||||||
if (stack == null) {
|
if (stack == null) {
|
||||||
replaceExistingItem(slot, item);
|
replaceExistingItem(slot, item);
|
||||||
return null;
|
return null;
|
||||||
|
Loading…
Reference in New Issue
Block a user