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

Small performance optimization for large Cargo networks

This commit is contained in:
TheBusyBiscuit 2020-07-06 22:04:32 +02:00
parent b243f128de
commit afd63a1f51
12 changed files with 230 additions and 134 deletions

View File

@ -63,7 +63,8 @@
* performance improvements to Generators and Electric Machines
* Cargo timings will now be attributed to the corresponding node and not the Cargo manager
* Thunderstorms now count as night time for Solar Generators
* Fixed an issue with moving androids getting stuck
* Coolant Cells can no longer be placed on the ground
* Crafting Nether Ice Coolant Cells now results in 4 items
#### Fixes
* Fixed #2005
@ -90,6 +91,8 @@
* Fixed Androids turning in the wrong direction
* Fixed contributors losing their texture after restarts
* Fixed "korean" showing up as "null"
* Fixed an issue with moving androids getting stuck
* Fixed Cargo nodes sometimes preventing chunks from unloading
## Release Candidate 13 (16 Jun 2020)
https://thebusybiscuit.github.io/builds/TheBusyBiscuit/Slimefun4/stable/#13

View File

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

View File

@ -8,7 +8,6 @@ import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
import java.util.logging.Level;
import org.bukkit.Location;
@ -243,9 +242,11 @@ public class CargoNet extends ChestTerminalNetwork {
private void run(Map<Location, Integer> inputs, Map<Integer, List<Location>> outputs, Set<Location> chestTerminalInputs, Set<Location> chestTerminalOutputs) {
long timestamp = System.nanoTime();
Map<Location, Inventory> inventories = new HashMap<>();
// Chest Terminal Code
if (SlimefunPlugin.getThirdPartySupportService().isChestTerminalInstalled()) {
handleItemRequests(chestTerminalInputs, chestTerminalOutputs);
handleItemRequests(inventories, chestTerminalInputs, chestTerminalOutputs);
}
// All operations happen here: Everything gets iterated from the Input Nodes.
@ -253,10 +254,10 @@ public class CargoNet extends ChestTerminalNetwork {
for (Map.Entry<Location, Integer> entry : inputs.entrySet()) {
long nodeTimestamp = System.nanoTime();
Location input = entry.getKey();
Optional<Block> attachedBlock = getAttachedBlock(input.getBlock());
Optional<Block> attachedBlock = getAttachedBlock(input);
if (attachedBlock.isPresent()) {
routeItems(input, attachedBlock.get(), entry.getValue(), outputs);
routeItems(inventories, input, attachedBlock.get(), entry.getValue(), outputs);
}
// This will prevent this timings from showing up for the Cargo Manager
@ -272,9 +273,8 @@ public class CargoNet extends ChestTerminalNetwork {
SlimefunPlugin.getProfiler().closeEntry(regulator, SlimefunItems.CARGO_MANAGER.getItem(), timestamp);
}
private void routeItems(Location inputNode, Block inputTarget, int frequency, Map<Integer, List<Location>> outputNodes) {
AtomicReference<Object> inventory = new AtomicReference<>();
ItemStackAndInteger slot = CargoUtils.withdraw(inputNode.getBlock(), inputTarget, inventory);
private void routeItems(Map<Location, Inventory> inventories, Location inputNode, Block inputTarget, int frequency, Map<Integer, List<Location>> outputNodes) {
ItemStackAndInteger slot = CargoUtils.withdraw(inventories, inputNode.getBlock(), inputTarget);
if (slot == null) {
return;
@ -285,26 +285,13 @@ public class CargoNet extends ChestTerminalNetwork {
List<Location> outputs = outputNodes.get(frequency);
if (outputs != null) {
stack = distributeItem(stack, inputNode, outputs);
stack = distributeItem(inventories, stack, inputNode, outputs);
}
if (stack != null) {
Object inputInventory = inventory.get();
if (inputInventory instanceof DirtyChestMenu) {
DirtyChestMenu menu = (DirtyChestMenu) inputInventory;
if (menu.getItemInSlot(previousSlot) == null) {
menu.replaceExistingItem(previousSlot, stack);
}
else {
inputTarget.getWorld().dropItem(inputTarget.getLocation().add(0, 1, 0), stack);
}
}
if (inputInventory instanceof Inventory) {
Inventory inv = (Inventory) inputInventory;
Inventory inv = inventories.get(inputTarget.getLocation());
if (inv != null) {
if (inv.getItem(previousSlot) == null) {
inv.setItem(previousSlot, stack);
}
@ -312,10 +299,22 @@ public class CargoNet extends ChestTerminalNetwork {
inputTarget.getWorld().dropItem(inputTarget.getLocation().add(0, 1, 0), stack);
}
}
else {
DirtyChestMenu menu = CargoUtils.getChestMenu(inputTarget);
if (menu != null) {
if (menu.getItemInSlot(previousSlot) == null) {
menu.replaceExistingItem(previousSlot, stack);
}
else {
inputTarget.getWorld().dropItem(inputTarget.getLocation().add(0, 1, 0), stack);
}
}
}
}
}
private ItemStack distributeItem(ItemStack stack, Location inputNode, List<Location> outputNodes) {
private ItemStack distributeItem(Map<Location, Inventory> inventories, ItemStack stack, Location inputNode, List<Location> outputNodes) {
ItemStack item = stack;
Deque<Location> destinations = new LinkedList<>(outputNodes);
@ -327,10 +326,10 @@ public class CargoNet extends ChestTerminalNetwork {
}
for (Location output : destinations) {
Optional<Block> target = getAttachedBlock(output.getBlock());
Optional<Block> target = getAttachedBlock(output);
if (target.isPresent()) {
item = CargoUtils.insert(output.getBlock(), target.get(), item);
item = CargoUtils.insert(inventories, output.getBlock(), target.get(), item);
if (item == null) {
break;

View File

@ -2,9 +2,10 @@ package io.github.thebusybiscuit.slimefun4.core.networks.cargo;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
import java.util.Map;
import java.util.logging.Level;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Tag;
import org.bukkit.block.Block;
@ -83,15 +84,23 @@ final class CargoUtils {
return false;
}
static ItemStack withdraw(Block node, Block target, ItemStack template) {
static ItemStack withdraw(Map<Location, Inventory> inventories, Block node, Block target, ItemStack template) {
DirtyChestMenu menu = getChestMenu(target);
if (menu == null) {
if (hasInventory(target)) {
Inventory inventory = inventories.get(target.getLocation());
if (inventory != null) {
return withdrawFromVanillaInventory(node, template, inventory);
}
BlockState state = target.getState();
if (state instanceof InventoryHolder) {
return withdrawFromVanillaInventory(node, template, ((InventoryHolder) state).getInventory());
inventory = ((InventoryHolder) state).getInventory();
inventories.put(target.getLocation(), inventory);
return withdrawFromVanillaInventory(node, template, inventory);
}
}
@ -154,7 +163,7 @@ final class CargoUtils {
return null;
}
static ItemStackAndInteger withdraw(Block node, Block target, AtomicReference<Object> inventory) {
static ItemStackAndInteger withdraw(Map<Location, Inventory> inventories, Block node, Block target) {
DirtyChestMenu menu = getChestMenu(target);
if (menu != null) {
@ -163,45 +172,55 @@ final class CargoUtils {
if (matchesFilter(node, is)) {
menu.replaceExistingItem(slot, null);
inventory.set(menu);
return new ItemStackAndInteger(is, slot);
}
}
}
else if (hasInventory(target)) {
Inventory inventory = inventories.get(target.getLocation());
if (inventory != null) {
return withdrawFromVanillaInventory(node, inventory);
}
BlockState state = target.getState();
if (state instanceof InventoryHolder) {
Inventory inv = ((InventoryHolder) state).getInventory();
ItemStack[] contents = inv.getContents();
int minSlot = 0;
int maxSlot = contents.length;
if (inv instanceof FurnaceInventory) {
minSlot = 2;
maxSlot = 3;
}
else if (inv instanceof BrewerInventory) {
maxSlot = 3;
}
for (int slot = minSlot; slot < maxSlot; slot++) {
ItemStack is = contents[slot];
if (matchesFilter(node, is)) {
inv.setItem(slot, null);
inventory.set(inv);
return new ItemStackAndInteger(is, slot);
}
}
inventory = ((InventoryHolder) state).getInventory();
inventories.put(target.getLocation(), inventory);
return withdrawFromVanillaInventory(node, inventory);
}
}
return null;
}
static ItemStack insert(Block node, Block target, ItemStack stack) {
private static ItemStackAndInteger withdrawFromVanillaInventory(Block node, Inventory inv) {
ItemStack[] contents = inv.getContents();
int minSlot = 0;
int maxSlot = contents.length;
if (inv instanceof FurnaceInventory) {
minSlot = 2;
maxSlot = 3;
}
else if (inv instanceof BrewerInventory) {
maxSlot = 3;
}
for (int slot = minSlot; slot < maxSlot; slot++) {
ItemStack is = contents[slot];
if (matchesFilter(node, is)) {
inv.setItem(slot, null);
return new ItemStackAndInteger(is, slot);
}
}
return null;
}
static ItemStack insert(Map<Location, Inventory> inventories, Block node, Block target, ItemStack stack) {
if (!matchesFilter(node, stack)) {
return stack;
}
@ -210,10 +229,18 @@ final class CargoUtils {
if (menu == null) {
if (hasInventory(target)) {
Inventory inventory = inventories.get(target.getLocation());
if (inventory != null) {
return insertIntoVanillaInventory(stack, inventory);
}
BlockState state = target.getState();
if (state instanceof InventoryHolder) {
return insertIntoVanillaInventory(stack, ((InventoryHolder) state).getInventory());
inventory = ((InventoryHolder) state).getInventory();
inventories.put(target.getLocation(), inventory);
return insertIntoVanillaInventory(stack, inventory);
}
}
@ -251,7 +278,7 @@ final class CargoUtils {
return stack;
}
static ItemStack insertIntoVanillaInventory(ItemStack stack, Inventory inv) {
private static ItemStack insertIntoVanillaInventory(ItemStack stack, Inventory inv) {
ItemStack[] contents = inv.getContents();
int minSlot = 0;
int maxSlot = contents.length;
@ -392,7 +419,7 @@ final class CargoUtils {
}
for (ItemStack stack : templateItems) {
if (SlimefunUtils.isItemSimilar(wrapper, stack, lore)) {
if (SlimefunUtils.isItemSimilar(wrapper, stack, lore, false)) {
return true;
}
}

View File

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

View File

@ -10,7 +10,6 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Level;
import org.apache.commons.lang.Validate;
import org.bukkit.Chunk;
@ -25,7 +24,6 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.tasks.TickerTask;
import io.github.thebusybiscuit.slimefun4.utils.NumberUtils;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.api.Slimefun;
/**
* The {@link SlimefunProfiler} works closely to the {@link TickerTask} and is
@ -41,7 +39,7 @@ import me.mrCookieSlime.Slimefun.api.Slimefun;
*/
public class SlimefunProfiler {
private final ExecutorService executor = Executors.newFixedThreadPool(3);
private final ExecutorService executor = Executors.newFixedThreadPool(4);
private final AtomicBoolean running = new AtomicBoolean(false);
private final AtomicInteger queued = new AtomicInteger(0);
@ -135,13 +133,9 @@ public class SlimefunProfiler {
// Wait for all timing results to come in
while (queued.get() > 0 && !running.get()) {
try {
Thread.sleep(1);
}
catch (InterruptedException e) {
Slimefun.getLogger().log(Level.SEVERE, "A waiting Thread was interrupted", e);
Thread.currentThread().interrupt();
}
// Ideally we would wait some time here but the ticker task may be faster
// than 1ms, so it would halt this summary for up to 7 minutes
// Not perfect performance-wise but this is a seperate Thread anyway
}
if (running.get()) {

View File

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

View File

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

View File

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

View File

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

View File

@ -138,6 +138,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.items.medical.Medicine;
import io.github.thebusybiscuit.slimefun4.implementation.items.medical.Rag;
import io.github.thebusybiscuit.slimefun4.implementation.items.medical.Splint;
import io.github.thebusybiscuit.slimefun4.implementation.items.medical.Vitamins;
import io.github.thebusybiscuit.slimefun4.implementation.items.misc.CoolantCell;
import io.github.thebusybiscuit.slimefun4.implementation.items.misc.OrganicFertilizer;
import io.github.thebusybiscuit.slimefun4.implementation.items.misc.OrganicFood;
import io.github.thebusybiscuit.slimefun4.implementation.items.multiblocks.ArmorForge;
@ -3028,12 +3029,13 @@ public final class SlimefunItemSetup {
}.register(plugin);
new SlimefunItem(categories.technicalComponents, SlimefunItems.REACTOR_COOLANT_CELL, RecipeType.FREEZER,
new CoolantCell(categories.technicalComponents, SlimefunItems.REACTOR_COOLANT_CELL, RecipeType.FREEZER,
new ItemStack[] {new ItemStack(Material.BLUE_ICE), null, null, null, null, null, null, null, null})
.register(plugin);
new SlimefunItem(categories.technicalComponents, SlimefunItems.NETHER_ICE_COOLANT_CELL, RecipeType.HEATED_PRESSURE_CHAMBER,
new ItemStack[] {SlimefunItems.ENRICHED_NETHER_ICE, null, null, null, null, null, null, null, null})
new CoolantCell(categories.technicalComponents, SlimefunItems.NETHER_ICE_COOLANT_CELL, RecipeType.HEATED_PRESSURE_CHAMBER,
new ItemStack[] {SlimefunItems.ENRICHED_NETHER_ICE, null, null, null, null, null, null, null, null},
new SlimefunItemStack(SlimefunItems.NETHER_ICE_COOLANT_CELL, 4))
.register(plugin);
new RadioactiveItem(categories.resources, Radioactivity.HIGH, SlimefunItems.NEPTUNIUM, RecipeType.NUCLEAR_REACTOR,

View File

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