mirror of
https://github.com/StarWishsama/Slimefun4.git
synced 2024-09-19 19:25:48 +00:00
More performance and memory improvements
This commit is contained in:
parent
bb764b7584
commit
15f281504f
@ -44,6 +44,8 @@
|
||||
* Performance improvements to Cargo network visualizations
|
||||
* General performance improvements
|
||||
* Improved performance for radioactive items
|
||||
* Memory/GC improvements for the profiler
|
||||
* Performance improvements for the Fluid Pump
|
||||
|
||||
#### Fixes
|
||||
* Fixed #2448
|
||||
|
@ -33,7 +33,7 @@ public class PlayerPreResearchEvent extends Event implements Cancellable {
|
||||
private final Research research;
|
||||
private final SlimefunItem slimefunItem;
|
||||
private boolean cancelled;
|
||||
|
||||
|
||||
@ParametersAreNonnullByDefault
|
||||
public PlayerPreResearchEvent(Player p, Research research, SlimefunItem slimefunItem) {
|
||||
Validate.notNull(p, "The Player cannot be null");
|
||||
|
@ -49,7 +49,9 @@ public interface DamageableItem extends ItemAttribute {
|
||||
*/
|
||||
default void damageItem(@Nonnull Player p, @Nullable ItemStack item) {
|
||||
if (isDamageable() && item != null && item.getType() != Material.AIR && item.getAmount() > 0) {
|
||||
if (item.getEnchantments().containsKey(Enchantment.DURABILITY) && Math.random() * 100 <= (60 + Math.floorDiv(40, (item.getEnchantmentLevel(Enchantment.DURABILITY) + 1)))) {
|
||||
int unbreakingLevel = item.getEnchantmentLevel(Enchantment.DURABILITY);
|
||||
|
||||
if (unbreakingLevel > 0 && Math.random() * 100 <= (60 + Math.floorDiv(40, (unbreakingLevel + 1)))) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -68,8 +68,11 @@ public abstract class FlexCategory extends Category {
|
||||
|
||||
@Override
|
||||
public final boolean isHidden(@Nonnull Player p) {
|
||||
// We can stop this method right here.
|
||||
// We provide a custom method with more parameters for this. See isVisible(...)
|
||||
/**
|
||||
* We can stop this method right here.
|
||||
* We provide a custom method with more parameters for this.
|
||||
* See isVisible(...)
|
||||
*/
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -153,9 +153,11 @@ public class LockedCategory extends Category {
|
||||
public boolean hasUnlocked(@Nonnull Player p, @Nonnull PlayerProfile profile) {
|
||||
for (Category category : parents) {
|
||||
for (SlimefunItem item : category.getItems()) {
|
||||
// Should probably be replaced with Slimefun.hasUnlocked(...)
|
||||
// However this will result in better performance because we don't
|
||||
// request the PlayerProfile everytime
|
||||
/**
|
||||
* Should probably be replaced with Slimefun.hasUnlocked(...)
|
||||
* However this will result in better performance because we don't
|
||||
* request the PlayerProfile everytime
|
||||
*/
|
||||
if (Slimefun.isEnabled(p, item, false) && Slimefun.hasPermission(p, item, false) && !profile.hasUnlocked(item.getResearch())) {
|
||||
return false;
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ public class SeasonalCategory extends Category {
|
||||
private final Month month;
|
||||
|
||||
/**
|
||||
* The constructor for a SeasonCategory.
|
||||
* The constructor for a {@link SeasonalCategory}.
|
||||
*
|
||||
* @param key
|
||||
* The {@link NamespacedKey} that is used to identify this {@link Category}
|
||||
|
@ -83,9 +83,12 @@ public class SlimefunCommand implements CommandExecutor, Listener {
|
||||
|
||||
sendHelp(sender);
|
||||
|
||||
// We could just return true here, but if there's no subcommands, then
|
||||
// something went horribly wrong anyway. This will also stop sonarcloud
|
||||
// from nagging about this always returning true...
|
||||
/**
|
||||
* We could just return true here, but if there's no subcommands,
|
||||
* then something went horribly wrong anyway.
|
||||
* This will also stop sonarcloud from nagging about
|
||||
* this always returning true...
|
||||
*/
|
||||
return !commands.isEmpty();
|
||||
}
|
||||
|
||||
|
@ -77,6 +77,7 @@ public abstract class SubCommand {
|
||||
*
|
||||
* @param sender
|
||||
* The {@link CommandSender} who requested the description
|
||||
*
|
||||
* @return A possibly localized description of this {@link SubCommand}
|
||||
*/
|
||||
@Nonnull
|
||||
|
@ -108,6 +108,7 @@ public class NetworkManager {
|
||||
}
|
||||
|
||||
Validate.notNull(type, "Type must not be null");
|
||||
|
||||
for (Network network : networks) {
|
||||
if (type.isInstance(network) && network.connectsTo(l)) {
|
||||
return Optional.of(type.cast(network));
|
||||
|
@ -117,6 +117,7 @@ public class Research implements Keyed {
|
||||
*
|
||||
* @param p
|
||||
* The {@link Player} to translate this name for.
|
||||
*
|
||||
* @return The localized Name of this {@link Research}.
|
||||
*/
|
||||
@Nonnull
|
||||
@ -197,12 +198,18 @@ public class Research implements Keyed {
|
||||
* Handle what to do when a {@link Player} clicks on an un-researched item in
|
||||
* a {@link SlimefunGuideImplementation}.
|
||||
*
|
||||
* @param guide The {@link SlimefunGuideImplementation} used.
|
||||
* @param player The {@link Player} who clicked on the item.
|
||||
* @param profile The {@link PlayerProfile} of that {@link Player}.
|
||||
* @param sfItem The {@link SlimefunItem} on which the {@link Player} clicked.
|
||||
* @param category The {@link Category} where the {@link Player} was.
|
||||
* @param page The page number of where the {@link Player} was in the {@link Category};
|
||||
* @param guide
|
||||
* The {@link SlimefunGuideImplementation} used.
|
||||
* @param player
|
||||
* The {@link Player} who clicked on the item.
|
||||
* @param profile
|
||||
* The {@link PlayerProfile} of that {@link Player}.
|
||||
* @param sfItem
|
||||
* The {@link SlimefunItem} on which the {@link Player} clicked.
|
||||
* @param category
|
||||
* The {@link Category} where the {@link Player} was.
|
||||
* @param page
|
||||
* The page number of where the {@link Player} was in the {@link Category};
|
||||
*
|
||||
*/
|
||||
@ParametersAreNonnullByDefault
|
||||
@ -230,6 +237,7 @@ public class Research implements Keyed {
|
||||
*
|
||||
* @param p
|
||||
* The {@link Player} to check
|
||||
*
|
||||
* @return Whether that {@link Player} can unlock this {@link Research}
|
||||
*/
|
||||
public boolean canUnlock(@Nonnull Player p) {
|
||||
|
@ -52,8 +52,10 @@ class GitHubTask implements Runnable {
|
||||
* the {@link UUID} and received skin inside a local cache {@link File}.
|
||||
*/
|
||||
private void grabTextures() {
|
||||
// Store all queried usernames to prevent 429 responses for pinging the
|
||||
// same URL twice in one run.
|
||||
/**
|
||||
* Store all queried usernames to prevent 429 responses for pinging
|
||||
* the same URL twice in one run.
|
||||
*/
|
||||
Map<String, String> skins = new HashMap<>();
|
||||
int requests = 0;
|
||||
|
||||
@ -77,8 +79,11 @@ class GitHubTask implements Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
// We only wanna save this if all Connectors finished already
|
||||
// This will run multiple times but thats okay, this way we get as much data as possible stored
|
||||
/**
|
||||
* We only wanna save this if all Connectors finished already.
|
||||
* This will run multiple times but thats okay, this way we get as much
|
||||
* data as possible stored.
|
||||
*/
|
||||
gitHubService.saveCache();
|
||||
}
|
||||
|
||||
|
@ -45,7 +45,7 @@ public enum PerformanceRating implements Predicate<Float> {
|
||||
@Override
|
||||
public boolean test(@Nullable Float value) {
|
||||
if (value == null) {
|
||||
// null will only test true for UNKNOWN
|
||||
// This way null will only test true for UNKNOWN
|
||||
return threshold < 0;
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,11 @@
|
||||
package io.github.thebusybiscuit.slimefun4.core.services.profiler;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
|
||||
import io.github.thebusybiscuit.cscorelib2.blocks.BlockPosition;
|
||||
@ -11,44 +14,129 @@ import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
|
||||
|
||||
/**
|
||||
* This represents an entry in our {@link SlimefunProfiler}.
|
||||
* It is a modification of {@link BlockPosition} to be as memory-efficient as possible.
|
||||
*
|
||||
* @author TheBusyBiscuit
|
||||
*
|
||||
*/
|
||||
class ProfiledBlock {
|
||||
final class ProfiledBlock {
|
||||
|
||||
private final BlockPosition position;
|
||||
/**
|
||||
* The {@link World} this {@link Block} is in.
|
||||
* It is fine to keep an actual reference here since this is a throwaway object anyway.
|
||||
*/
|
||||
private final World world;
|
||||
|
||||
/**
|
||||
* A {@link Long} representation of our {@link Location} (x, y, z).
|
||||
*/
|
||||
private final long position;
|
||||
|
||||
/**
|
||||
* The {@link SlimefunItem} whihc is located at this {@link Location}.
|
||||
*/
|
||||
private final SlimefunItem item;
|
||||
|
||||
/**
|
||||
* This creates a new {@link ProfiledBlock} for the given {@link Location} and
|
||||
* the {@link SlimefunItem} found at this {@link Location}.
|
||||
*
|
||||
* @param l
|
||||
* The {@link Location}
|
||||
* @param item
|
||||
* The {@link SlimefunItem} found at that {@link Location}
|
||||
*/
|
||||
ProfiledBlock(@Nonnull Location l, @Nonnull SlimefunItem item) {
|
||||
this.position = new BlockPosition(l);
|
||||
this.item = item;
|
||||
}
|
||||
|
||||
ProfiledBlock(@Nonnull BlockPosition position, @Nonnull SlimefunItem item) {
|
||||
this.position = position;
|
||||
this.world = l.getWorld();
|
||||
this.position = getLocationAsLong((int) l.getX(), (int) l.getY(), (int) l.getZ());
|
||||
this.item = item;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is just a <strong>dummy</strong> constructor.
|
||||
* Please only use this for comparisons or lookups.
|
||||
*
|
||||
* @param b
|
||||
* A {@link Block}
|
||||
*/
|
||||
ProfiledBlock(@Nonnull Block b) {
|
||||
this.position = new BlockPosition(b);
|
||||
this.world = b.getWorld();
|
||||
this.position = getLocationAsLong(b.getX(), b.getY(), b.getZ());
|
||||
this.item = null;
|
||||
}
|
||||
|
||||
public BlockPosition getPosition() {
|
||||
return position;
|
||||
/**
|
||||
* This compresses our {@link Location} into a long for more efficient memory usage
|
||||
*
|
||||
* @param x
|
||||
* The x value
|
||||
* @param y
|
||||
* The y value
|
||||
* @param z
|
||||
* The z value
|
||||
*
|
||||
* @return A {@link Long} representation of this {@link Location}
|
||||
*/
|
||||
private static long getLocationAsLong(int x, int y, int z) {
|
||||
return ((long) (x & 0x3FFFFFF) << 38) | ((long) (z & 0x3FFFFFF) << 12) | (long) (y & 0xFFF);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public World getWorld() {
|
||||
return world;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the x for this block.
|
||||
*
|
||||
* @return This blocks x coordinate.
|
||||
*/
|
||||
public int getX() {
|
||||
return (int) (this.position >> 38);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the y for this block.
|
||||
*
|
||||
* @return This blocks y coordinate.
|
||||
*/
|
||||
public int getY() {
|
||||
return (int) (this.position & 0xFFF);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the z for this block.
|
||||
*
|
||||
* @return This blocks z coordinate.
|
||||
*/
|
||||
public int getZ() {
|
||||
return (int) (this.position << 26 >> 38);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the chunks x coordinate for this block.
|
||||
*
|
||||
* @return The blocks chunks x coordinate.
|
||||
*/
|
||||
public int getChunkX() {
|
||||
return this.getX() >> 4;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the chunks z coordinate for this block.
|
||||
*
|
||||
* @return The blocks chunks z coordinate.
|
||||
*/
|
||||
public int getChunkZ() {
|
||||
return this.getZ() >> 4;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public String getId() {
|
||||
return item.getId();
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public SlimefunAddon getAddon() {
|
||||
return item.getAddon();
|
||||
}
|
||||
@ -56,7 +144,8 @@ class ProfiledBlock {
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof ProfiledBlock) {
|
||||
return position.equals(((ProfiledBlock) obj).position);
|
||||
ProfiledBlock block = (ProfiledBlock) obj;
|
||||
return position == block.position && Objects.equals(world, block.world);
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -64,7 +153,8 @@ class ProfiledBlock {
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return position.hashCode();
|
||||
long hilo = world.getUID().getMostSignificantBits() ^ world.getUID().getLeastSignificantBits();
|
||||
return (int) (position ^ (position >> 32) ^ hilo ^ (hilo >> 32));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -50,6 +50,7 @@ public class SlimefunProfiler {
|
||||
|
||||
private final SlimefunThreadFactory threadFactory = new SlimefunThreadFactory(5);
|
||||
private final ExecutorService executor = Executors.newFixedThreadPool(threadFactory.getThreadCount(), threadFactory);
|
||||
|
||||
private final AtomicBoolean running = new AtomicBoolean(false);
|
||||
private final AtomicInteger queued = new AtomicInteger(0);
|
||||
|
||||
@ -234,9 +235,10 @@ public class SlimefunProfiler {
|
||||
Map<String, Long> map = new HashMap<>();
|
||||
|
||||
for (Map.Entry<ProfiledBlock, Long> entry : timings.entrySet()) {
|
||||
String world = entry.getKey().getPosition().getWorld().getName();
|
||||
int x = entry.getKey().getPosition().getChunkX();
|
||||
int z = entry.getKey().getPosition().getChunkZ();
|
||||
ProfiledBlock block = entry.getKey();
|
||||
String world = block.getWorld().getName();
|
||||
int x = block.getChunkX();
|
||||
int z = block.getChunkZ();
|
||||
|
||||
map.merge(world + " (" + x + ',' + z + ')', entry.getValue(), Long::sum);
|
||||
}
|
||||
@ -249,9 +251,9 @@ public class SlimefunProfiler {
|
||||
int blocks = 0;
|
||||
|
||||
for (ProfiledBlock block : timings.keySet()) {
|
||||
String world = block.getPosition().getWorld().getName();
|
||||
int x = block.getPosition().getChunkX();
|
||||
int z = block.getPosition().getChunkZ();
|
||||
String world = block.getWorld().getName();
|
||||
int x = block.getChunkX();
|
||||
int z = block.getChunkZ();
|
||||
|
||||
if (chunk.equals(world + " (" + x + ',' + z + ')')) {
|
||||
blocks++;
|
||||
@ -290,6 +292,7 @@ public class SlimefunProfiler {
|
||||
protected float getPercentageOfTick() {
|
||||
float millis = totalElapsedTime / 1000000.0F;
|
||||
float fraction = (millis * 100.0F) / MAX_TICK_DURATION;
|
||||
|
||||
return Math.round((fraction * 100.0F) / 100.0F);
|
||||
}
|
||||
|
||||
@ -311,6 +314,7 @@ public class SlimefunProfiler {
|
||||
return PerformanceRating.UNKNOWN;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public String getTime() {
|
||||
return NumberUtils.getAsMillis(totalElapsedTime);
|
||||
}
|
||||
@ -330,6 +334,7 @@ public class SlimefunProfiler {
|
||||
*/
|
||||
public boolean hasTimings(@Nonnull Block b) {
|
||||
Validate.notNull("Cannot get timings for a null Block");
|
||||
|
||||
return timings.containsKey(new ProfiledBlock(b));
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,8 @@ package io.github.thebusybiscuit.slimefun4.core.services.profiler;
|
||||
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
/**
|
||||
* This is our {@link ThreadFactory} for the {@link SlimefunProfiler}.
|
||||
* It holds the amount of {@link Thread Threads} we dedicate towards our {@link SlimefunProfiler}
|
||||
@ -16,16 +18,31 @@ final class SlimefunThreadFactory implements ThreadFactory {
|
||||
|
||||
private final int threadCount;
|
||||
|
||||
/**
|
||||
* This constructs a new {@link SlimefunThreadFactory} with the given {@link Thread} count.
|
||||
*
|
||||
* @param threadCount
|
||||
* The amount of {@link Thread Threads} to provide to the {@link SlimefunProfiler}
|
||||
*/
|
||||
SlimefunThreadFactory(int threadCount) {
|
||||
this.threadCount = threadCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* This returns the amount of {@link Thread Threads} we dedicate towards
|
||||
* the {@link SlimefunProfiler}.
|
||||
*
|
||||
* @return The {@link Thread} count
|
||||
*/
|
||||
int getThreadCount() {
|
||||
return threadCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* This creates a new {@link Thread} for the {@link SlimefunProfiler}.
|
||||
*/
|
||||
@Override
|
||||
public Thread newThread(Runnable runnable) {
|
||||
public Thread newThread(@Nonnull Runnable runnable) {
|
||||
return new Thread(runnable, "Slimefun Profiler");
|
||||
}
|
||||
|
||||
|
@ -215,11 +215,7 @@ public class BookSlimefunGuide implements SlimefunGuideImplementation {
|
||||
|
||||
ChatComponent component = new ChatComponent(ChatUtils.crop(ChatColor.RED, item.getItemName()) + "\n");
|
||||
component.setHoverEvent(new HoverEvent(ChatColor.RESET + item.getItemName(), ChatColor.DARK_RED.toString() + ChatColor.BOLD + SlimefunPlugin.getLocalization().getMessage(p, "guide.locked"), "", ChatColor.GREEN + "> Click to unlock", "", ChatColor.GRAY + "Cost: " + ChatColor.AQUA.toString() + research.getCost() + " Level(s)"));
|
||||
component.setClickEvent(new ClickEvent(key, player ->
|
||||
SlimefunPlugin.runSync(() ->
|
||||
research.unlockFromGuide(this, player, profile, item, category, page)
|
||||
)
|
||||
));
|
||||
component.setClickEvent(new ClickEvent(key, player -> SlimefunPlugin.runSync(() -> research.unlockFromGuide(this, player, profile, item, category, page))));
|
||||
|
||||
items.add(component);
|
||||
} else {
|
||||
|
@ -2,6 +2,10 @@ package io.github.thebusybiscuit.slimefun4.implementation.items.electric.machine
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
@ -13,12 +17,12 @@ import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import io.github.thebusybiscuit.cscorelib2.blocks.Vein;
|
||||
import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
|
||||
import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetComponent;
|
||||
import io.github.thebusybiscuit.slimefun4.core.networks.energy.EnergyNetComponentType;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
|
||||
import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils;
|
||||
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
|
||||
import io.github.thebusybiscuit.slimefun4.utils.itemstack.ItemStackWrapper;
|
||||
import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config;
|
||||
import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu.AdvancedMenuClickHandler;
|
||||
import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ClickAction;
|
||||
@ -49,6 +53,9 @@ public class FluidPump extends SimpleSlimefunItem<BlockTicker> implements Invent
|
||||
private final int[] inputBorder = { 9, 10, 11, 12, 18, 21, 27, 28, 29, 30 };
|
||||
private final int[] outputBorder = { 14, 15, 16, 17, 23, 26, 32, 33, 34, 35 };
|
||||
|
||||
private final ItemStack emptyBucket = new ItemStackWrapper(Material.BUCKET);
|
||||
|
||||
@ParametersAreNonnullByDefault
|
||||
public FluidPump(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
||||
super(category, item, recipeType, recipe);
|
||||
|
||||
@ -66,16 +73,16 @@ public class FluidPump extends SimpleSlimefunItem<BlockTicker> implements Invent
|
||||
});
|
||||
}
|
||||
|
||||
private void constructMenu(BlockMenuPreset preset) {
|
||||
private void constructMenu(@Nonnull BlockMenuPreset preset) {
|
||||
for (int i : border) {
|
||||
preset.addItem(i, new CustomItem(Material.GRAY_STAINED_GLASS_PANE, " "), ChestMenuUtils.getEmptyClickHandler());
|
||||
preset.addItem(i, ChestMenuUtils.getBackground(), ChestMenuUtils.getEmptyClickHandler());
|
||||
}
|
||||
|
||||
for (int i : inputBorder) {
|
||||
preset.addItem(i, new CustomItem(Material.CYAN_STAINED_GLASS_PANE, " "), ChestMenuUtils.getEmptyClickHandler());
|
||||
preset.addItem(i, ChestMenuUtils.getInputSlotTexture(), ChestMenuUtils.getEmptyClickHandler());
|
||||
}
|
||||
for (int i : outputBorder) {
|
||||
preset.addItem(i, new CustomItem(Material.ORANGE_STAINED_GLASS_PANE, " "), ChestMenuUtils.getEmptyClickHandler());
|
||||
preset.addItem(i, ChestMenuUtils.getOutputSlotTexture(), ChestMenuUtils.getEmptyClickHandler());
|
||||
}
|
||||
|
||||
for (int i : getOutputSlots()) {
|
||||
@ -114,14 +121,14 @@ public class FluidPump extends SimpleSlimefunItem<BlockTicker> implements Invent
|
||||
return 512;
|
||||
}
|
||||
|
||||
protected void tick(Block b) {
|
||||
protected void tick(@Nonnull Block b) {
|
||||
Block fluid = b.getRelative(BlockFace.DOWN);
|
||||
|
||||
if (fluid.isLiquid() && getCharge(b.getLocation()) >= ENERGY_CONSUMPTION) {
|
||||
BlockMenu menu = BlockStorage.getInventory(b);
|
||||
|
||||
for (int slot : getInputSlots()) {
|
||||
if (SlimefunUtils.isItemSimilar(menu.getItemInSlot(slot), new ItemStack(Material.BUCKET), true, false)) {
|
||||
if (SlimefunUtils.isItemSimilar(menu.getItemInSlot(slot), emptyBucket, true, false)) {
|
||||
ItemStack bucket = getFilledBucket(fluid);
|
||||
|
||||
if (!menu.fits(bucket, getOutputSlots())) {
|
||||
@ -143,11 +150,14 @@ public class FluidPump extends SimpleSlimefunItem<BlockTicker> implements Invent
|
||||
}
|
||||
}
|
||||
|
||||
private Block findNextFluid(Block fluid) {
|
||||
@Nullable
|
||||
private Block findNextFluid(@Nonnull Block fluid) {
|
||||
if (fluid.getType() == Material.WATER || fluid.getType() == Material.BUBBLE_COLUMN) {
|
||||
// With water we can be sure to find an infinite source whenever we go
|
||||
// further than a block, so we can just remove the water here and save
|
||||
// ourselves all of that computing...
|
||||
/**
|
||||
* With water we can be sure to find an infinite source whenever we
|
||||
* go further than a block, so we can just remove the water here and
|
||||
* save ourselves all of that computing...
|
||||
*/
|
||||
if (isSource(fluid)) {
|
||||
return fluid;
|
||||
}
|
||||
@ -162,10 +172,12 @@ public class FluidPump extends SimpleSlimefunItem<BlockTicker> implements Invent
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private ItemStack getFilledBucket(Block fluid) {
|
||||
@Nonnull
|
||||
private ItemStack getFilledBucket(@Nonnull Block fluid) {
|
||||
if (fluid.getType() == Material.LAVA) {
|
||||
return new ItemStack(Material.LAVA_BUCKET);
|
||||
} else if (fluid.getType() == Material.WATER || fluid.getType() == Material.BUBBLE_COLUMN) {
|
||||
@ -184,7 +196,7 @@ public class FluidPump extends SimpleSlimefunItem<BlockTicker> implements Invent
|
||||
*
|
||||
* @return Whether that {@link Block} is a liquid and a source {@link Block}.
|
||||
*/
|
||||
private boolean isSource(Block block) {
|
||||
private boolean isSource(@Nonnull Block block) {
|
||||
if (block.isLiquid()) {
|
||||
BlockData data = block.getBlockData();
|
||||
|
||||
|
@ -35,6 +35,7 @@ public class TeleporterListener implements Listener {
|
||||
}
|
||||
|
||||
String id = BlockStorage.checkID(e.getClickedBlock());
|
||||
|
||||
if (id == null) {
|
||||
return;
|
||||
}
|
||||
@ -55,7 +56,13 @@ public class TeleporterListener implements Listener {
|
||||
|
||||
@ParametersAreNonnullByDefault
|
||||
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()));
|
||||
if (id.equals(SlimefunItems.GPS_ACTIVATION_DEVICE_SHARED.getItemId())) {
|
||||
return true;
|
||||
} else if (id.equals(SlimefunItems.GPS_ACTIVATION_DEVICE_PERSONAL.getItemId())) {
|
||||
return BlockStorage.getLocationInfo(b.getLocation(), "owner").equals(uuid.toString());
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean checkForPylons(@Nonnull Block teleporter) {
|
||||
|
@ -7,12 +7,12 @@ import org.bukkit.entity.Player;
|
||||
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||
|
||||
abstract class PlayerTask implements Runnable {
|
||||
abstract class AbstractPlayerTask implements Runnable {
|
||||
|
||||
protected int id;
|
||||
protected Player p;
|
||||
|
||||
PlayerTask(@Nonnull Player p) {
|
||||
AbstractPlayerTask(@Nonnull Player p) {
|
||||
this.p = p;
|
||||
}
|
||||
|
||||
@ -36,10 +36,10 @@ abstract class PlayerTask implements Runnable {
|
||||
}
|
||||
|
||||
/**
|
||||
* This method checks if this {@link PlayerTask} should be continued or cancelled.
|
||||
* It will also cancel this {@link PlayerTask} if it became invalid.
|
||||
* This method checks if this {@link AbstractPlayerTask} should be continued or cancelled.
|
||||
* It will also cancel this {@link AbstractPlayerTask} if it became invalid.
|
||||
*
|
||||
* @return Whether this {@link PlayerTask} is still valid
|
||||
* @return Whether this {@link AbstractPlayerTask} is still valid
|
||||
*/
|
||||
protected boolean isValid() {
|
||||
if (!p.isOnline() || !p.isValid() || p.isDead() || !p.isSneaking()) {
|
@ -34,8 +34,9 @@ public class CapacitorTextureUpdateTask implements Runnable {
|
||||
@Override
|
||||
public void run() {
|
||||
Block b = l.getBlock();
|
||||
Material type = b.getType();
|
||||
|
||||
if (b.getType() == Material.PLAYER_HEAD || b.getType() == Material.PLAYER_WALL_HEAD) {
|
||||
if (type == Material.PLAYER_HEAD || type == Material.PLAYER_WALL_HEAD) {
|
||||
if (filledPercentage <= 0.25) {
|
||||
SkullBlock.setFromHash(b, HeadTexture.CAPACITOR_25.getTexture());
|
||||
} else if (filledPercentage <= 0.5) {
|
||||
|
@ -14,7 +14,7 @@ import org.bukkit.util.Vector;
|
||||
import io.github.thebusybiscuit.cscorelib2.math.DoubleHandler;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.gadgets.JetBoots;
|
||||
|
||||
public class JetBootsTask extends PlayerTask {
|
||||
public class JetBootsTask extends AbstractPlayerTask {
|
||||
|
||||
private static final float COST = 0.075F;
|
||||
|
||||
|
@ -11,7 +11,7 @@ import org.bukkit.util.Vector;
|
||||
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.gadgets.Jetpack;
|
||||
|
||||
public class JetpackTask extends PlayerTask {
|
||||
public class JetpackTask extends AbstractPlayerTask {
|
||||
|
||||
private static final float COST = 0.08F;
|
||||
|
||||
|
@ -13,7 +13,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.items.magical.InfusedMa
|
||||
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
|
||||
|
||||
/**
|
||||
* This {@link PlayerTask} is run when a {@link Player} carries an {@link InfusedMagnet}.
|
||||
* This {@link AbstractPlayerTask} is run when a {@link Player} carries an {@link InfusedMagnet}.
|
||||
* It manages the automatic pickup of nearby items.
|
||||
*
|
||||
* @author TheBusyBiscuit
|
||||
@ -21,7 +21,7 @@ import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
|
||||
* @see InfusedMagnet
|
||||
*
|
||||
*/
|
||||
public class MagnetTask extends PlayerTask {
|
||||
public class MagnetTask extends AbstractPlayerTask {
|
||||
|
||||
private final double radius;
|
||||
|
||||
|
@ -6,7 +6,7 @@ import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public class ParachuteTask extends PlayerTask {
|
||||
public class ParachuteTask extends AbstractPlayerTask {
|
||||
|
||||
public ParachuteTask(@Nonnull Player p) {
|
||||
super(p);
|
||||
|
@ -83,6 +83,7 @@ public class SlimefunStartupTask implements Runnable {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -146,8 +146,11 @@ public class TickerTask implements Runnable {
|
||||
if (item.getBlockTicker().isSynchronized()) {
|
||||
SlimefunPlugin.getProfiler().scheduleEntries(1);
|
||||
item.getBlockTicker().update();
|
||||
// We are inserting a new timestamp because synchronized
|
||||
// actions are always ran with a 50ms delay (1 game tick)
|
||||
|
||||
/**
|
||||
* We are inserting a new timestamp because synchronized actions
|
||||
* are always ran with a 50ms delay (1 game tick)
|
||||
*/
|
||||
SlimefunPlugin.runSync(() -> {
|
||||
Block b = l.getBlock();
|
||||
tickBlock(l, b, item, data, System.nanoTime());
|
||||
|
@ -42,6 +42,10 @@ public final class ItemStackWrapper extends ItemStack {
|
||||
}
|
||||
}
|
||||
|
||||
public ItemStackWrapper(@Nonnull Material material) {
|
||||
this(new ItemStack(material));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasItemMeta() {
|
||||
return hasItemMeta;
|
||||
|
Loading…
Reference in New Issue
Block a user