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

Added Iron Golem Assembler (experimental)

This commit is contained in:
TheBusyBiscuit 2020-07-23 12:02:53 +02:00
commit 1f7b75b823
52 changed files with 589 additions and 340 deletions

View File

@ -27,6 +27,8 @@
* Added Bee protection to Hazmat Suit
* Added Enchantment Rune
* Added Tape Measure
* Added "Bone Block -> Bone meal" recipe to the Grind Stone
* Added Iron Golem Assembler
#### Changes
* Refactored and reworked the Generator API
@ -36,11 +38,16 @@
* Changed recipe of Hazmat Suits
* Uranium can no longer be placed down
* Huge performance improvements when using Paper
* Optimized Cargo networks for Paper
* Optimized Multiblocks for Paper
* Optimized Enhanced Furnaces for Paper
#### Fixes
* Fixed Slimefun Armor sometimes not applying its effects
* Fixed #2075
* Fixed #2093
* Fixed #2086
* Fixed #1894
## Release Candidate 14 (12 Jul 2020)

View File

@ -19,8 +19,8 @@ public class ResearchUnlockEvent extends Event implements Cancellable {
private static final HandlerList handlers = new HandlerList();
private Player player;
private Research research;
private final Player player;
private final Research research;
private boolean cancelled;
public HandlerList getHandlers() {

View File

@ -28,8 +28,8 @@ public class Waypoint {
private final PlayerProfile profile;
private final String id;
private String name;
private Location location;
private final String name;
private final Location location;
public Waypoint(PlayerProfile profile, String id, Location l, String name) {
Validate.notNull(profile, "Profile must never be null!");

View File

@ -29,7 +29,7 @@ public abstract class Network {
private final NetworkManager manager;
protected Location regulator;
private Queue<Location> nodeQueue = new ArrayDeque<>();
private final Queue<Location> nodeQueue = new ArrayDeque<>();
protected final Set<Location> connectedLocations = new HashSet<>();
protected final Set<Location> regulatorNodes = new HashSet<>();

View File

@ -446,9 +446,7 @@ public final class PlayerProfile {
fromUUID(UUID.fromString(uuid), profile -> {
Optional<PlayerBackpack> backpack = profile.getBackpack(number);
if (backpack.isPresent()) {
callback.accept(backpack.get());
}
backpack.ifPresent(callback);
});
}
}

View File

@ -29,6 +29,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.guide.BookSlimefunGuide;
import io.github.thebusybiscuit.slimefun4.implementation.guide.CheatSheetSlimefunGuide;
import io.github.thebusybiscuit.slimefun4.implementation.guide.ChestSlimefunGuide;
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.AutomatedCraftingChamber;
import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.Objects.SlimefunBlockHandler;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
@ -196,10 +197,6 @@ public class SlimefunRegistry {
return mobDrops;
}
public Set<ItemStack> getMobDrops(EntityType entity) {
return mobDrops.get(entity);
}
public Set<SlimefunItem> getRadioactiveItems() {
return radioactive;
}
@ -256,6 +253,13 @@ public class SlimefunRegistry {
return geoResources;
}
/**
* This method returns a list of recipes for the {@link AutomatedCraftingChamber}
*
* @deprecated This just a really bad way to do this. Someone needs to rewrite this.
*
* @return A list of recipes for the {@link AutomatedCraftingChamber}
*/
@Deprecated
public Map<String, ItemStack> getAutomatedCraftingChamberRecipes() {
return automatedCraftingChamberRecipes;

View File

@ -29,7 +29,7 @@ final class RechargeableHelper {
private static final NamespacedKey CHARGE_KEY = new NamespacedKey(SlimefunPlugin.instance(), "item_charge");
private static final String LORE_PREFIX = ChatColors.color("&8\u21E8 &e\u26A1 &7");
private static final Pattern REGEX = Pattern.compile(ChatColors.color("(&c&o)?" + LORE_PREFIX) + "[0-9\\.]+ \\/ [0-9\\.]+ J");
private static final Pattern REGEX = Pattern.compile(ChatColors.color("(&c&o)?" + LORE_PREFIX) + "[0-9.]+ / [0-9.]+ J");
private RechargeableHelper() {}

View File

@ -54,6 +54,16 @@ public abstract class MultiBlockMachine extends SlimefunItem implements NotPlace
this.displayRecipes = new ArrayList<>();
this.displayRecipes.addAll(Arrays.asList(machineRecipes));
this.multiblock = new MultiBlock(this, convertItemStacksToMaterial(recipe), trigger);
registerDefaultRecipes(displayRecipes);
}
public MultiBlockMachine(Category category, SlimefunItemStack item, ItemStack[] recipe, BlockFace trigger) {
this(category, item, recipe, new ItemStack[0], trigger);
}
protected void registerDefaultRecipes(List<ItemStack> recipes) {
// Override this method to register some default recipes
}
public List<ItemStack[]> getRecipes() {

View File

@ -68,9 +68,7 @@ class CargoNetworkTask implements Runnable {
Location input = entry.getKey();
Optional<Block> attachedBlock = network.getAttachedBlock(input);
if (attachedBlock.isPresent()) {
routeItems(input, attachedBlock.get(), entry.getValue(), outputs);
}
attachedBlock.ifPresent(block -> routeItems(input, block, entry.getValue(), outputs));
// This will prevent this timings from showing up for the Cargo Manager
timestamp += SlimefunPlugin.getProfiler().closeEntry(entry.getKey(), SlimefunItems.CARGO_INPUT_NODE.getItem(), nodeTimestamp);

View File

@ -226,9 +226,7 @@ abstract class ChestTerminalNetwork extends Network {
if (menu.getItemInSlot(17) != null) {
Optional<Block> target = getAttachedBlock(bus);
if (target.isPresent()) {
menu.replaceExistingItem(17, CargoUtils.insert(inventories, bus.getBlock(), target.get(), menu.getItemInSlot(17)));
}
target.ifPresent(block -> menu.replaceExistingItem(17, CargoUtils.insert(inventories, bus.getBlock(), block, menu.getItemInSlot(17))));
}
if (menu.getItemInSlot(17) == null) {

View File

@ -41,7 +41,7 @@ public class Research implements Keyed {
private final NamespacedKey key;
private final int id;
private String name;
private final String name;
private boolean enabled = true;
private int cost;

View File

@ -206,9 +206,7 @@ public class GitHubService {
for (Contributor contributor : contributors.values()) {
Optional<UUID> uuid = contributor.getUniqueId();
if (uuid.isPresent()) {
uuidCache.setValue(contributor.getName(), uuid.get());
}
uuid.ifPresent(value -> uuidCache.setValue(contributor.getName(), value));
if (contributor.hasTexture()) {
String texture = contributor.getTexture();

View File

@ -116,9 +116,7 @@ class GitHubTask implements Runnable {
if (!uuid.isPresent()) {
uuid = MinecraftAccount.getUUID(contributor.getMinecraftName());
if (uuid.isPresent()) {
contributor.setUniqueId(uuid.get());
}
uuid.ifPresent(contributor::setUniqueId);
}
if (uuid.isPresent()) {

View File

@ -45,7 +45,7 @@ public final class SlimefunItems {
public static final SlimefunItemStack REPAIRED_SPAWNER = new SlimefunItemStack("REINFORCED_SPAWNER", Material.SPAWNER, "&bReinforced Spawner", "&7Type: &b<Type>");
public static final SlimefunItemStack INFERNAL_BONEMEAL = new SlimefunItemStack("INFERNAL_BONEMEAL", Material.BONE_MEAL, "&4Infernal Bonemeal", "", "&cSpeeds up the Growth of", "&cNether Warts as well");
public static final SlimefunItemStack TAPE_MEASURE = new SlimefunItemStack("TAPE_MEASURE", "180d5c43a6cf5bb7769fd0c8240e1e70d2ae38ef9d78a1db401aca6a2cb36f65", "&6Tape Measure", "", "&eCrouch & Right Click &7to set an anchor", "&eRight Click &7to measure");
/* Gadgets */
public static final SlimefunItemStack GOLD_PAN = new SlimefunItemStack("GOLD_PAN", Material.BOWL, "&6Gold Pan", "", "&eRight Click&7 to collect resources", "&7from Gravel");
public static final SlimefunItemStack NETHER_GOLD_PAN = new SlimefunItemStack("NETHER_GOLD_PAN", Material.BOWL, "&4Nether Gold Pan", "", "&eRight Click&7 to collect resources", "&7from Soul Sand");
@ -815,6 +815,7 @@ public final class SlimefunItems {
public static final SlimefunItemStack FLUID_PUMP = new SlimefunItemStack("FLUID_PUMP", Material.BLUE_TERRACOTTA, "&9Fluid Pump", "", LoreBuilder.machine(MachineTier.ADVANCED, MachineType.MACHINE), "&8\u21E8 &e\u26A1 &732 J/Block");
public static final SlimefunItemStack CHARGING_BENCH = new SlimefunItemStack("CHARGING_BENCH", Material.CRAFTING_TABLE, "&6Charging Bench", "", "&fCharges Items such as Jetpacks", "", LoreBuilder.machine(MachineTier.BASIC, MachineType.MACHINE), LoreBuilder.powerBuffer(128), "&8\u21E8 &e\u26A1 &7Energy Loss: &c50%");
public static final SlimefunItemStack IRON_GOLEM_ASSEMBLER = new SlimefunItemStack("IRON_GOLEM_ASSEMBLER", Material.IRON_BLOCK, "&6Iron Golem Assembler", "", LoreBuilder.machine(MachineTier.END_GAME, MachineType.MACHINE), "&8\u21E8 &7Cooldown: &b30 Seconds", LoreBuilder.powerBuffer(4096), "&8\u21E8 &e\u26A1 &72048 J/Golem");
public static final SlimefunItemStack WITHER_ASSEMBLER = new SlimefunItemStack("WITHER_ASSEMBLER", Material.OBSIDIAN, "&5Wither Assembler", "", LoreBuilder.machine(MachineTier.END_GAME, MachineType.MACHINE), "&8\u21E8 &7Cooldown: &b30 Seconds", LoreBuilder.powerBuffer(4096), "&8\u21E8 &e\u26A1 &74096 J/Wither");
public static final SlimefunItemStack TRASH_CAN = new SlimefunItemStack("TRASH_CAN_BLOCK", HeadTexture.TRASH_CAN, "&3Trash Can", "", "&fWill destroy all Items put into it");

View File

@ -31,7 +31,7 @@ class RecipeChoiceTask implements Runnable {
private Inventory inventory;
private int id;
private Map<Integer, LoopIterator<Material>> iterators = new HashMap<>();
private final Map<Integer, LoopIterator<Material>> iterators = new HashMap<>();
/**
* This will start this task for the given {@link Inventory}.

View File

@ -69,9 +69,7 @@ public abstract class WoodcutterAndroid extends ProgrammableAndroid {
if (log.getY() == android.getRelative(face).getY()) {
Optional<Material> sapling = MaterialConverter.getSaplingFromLog(log.getType());
if (sapling.isPresent()) {
log.setType(sapling.get());
}
sapling.ifPresent(log::setType);
}
else {
log.setType(Material.AIR);

View File

@ -31,7 +31,7 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
public class BlockPlacer extends SimpleSlimefunItem<BlockDispenseHandler> {
private ItemSetting<List<String>> blacklist = new ItemSetting<>("unplaceable-blocks", MaterialCollections.getAllUnbreakableBlocks().stream().map(Material::name).collect(Collectors.toList()));
private final ItemSetting<List<String>> blacklist = new ItemSetting<>("unplaceable-blocks", MaterialCollections.getAllUnbreakableBlocks().stream().map(Material::name).collect(Collectors.toList()));
public BlockPlacer(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(category, item, recipeType, recipe);

View File

@ -46,7 +46,7 @@ public class CargoManager extends SlimefunItem {
}, new BlockUseHandler() {
private String visualizerKey = "visualizer";
private final String visualizerKey = "visualizer";
@Override
public void onRightClick(PlayerRightClickEvent e) {

View File

@ -0,0 +1,293 @@
package io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
import io.github.thebusybiscuit.cscorelib2.math.DoubleHandler;
import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction;
import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetComponent;
import io.github.thebusybiscuit.slimefun4.core.networks.energy.EnergyNetComponentType;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils;
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config;
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.Objects.SlimefunBlockHandler;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.UnregisterReason;
import me.mrCookieSlime.Slimefun.Objects.handlers.BlockTicker;
import me.mrCookieSlime.Slimefun.api.BlockStorage;
import me.mrCookieSlime.Slimefun.api.Slimefun;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
import me.mrCookieSlime.Slimefun.api.energy.ChargableBlock;
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu;
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset;
import me.mrCookieSlime.Slimefun.api.inventory.DirtyChestMenu;
import me.mrCookieSlime.Slimefun.api.item_transport.ItemTransportFlow;
/**
* This is an abstract super class for Entity Assemblers.
*
* @author TheBusyBiscuit
*
* @see WitherAssembler
* @see IronGolemAssembler
*
*/
public abstract class AbstractEntityAssembler extends SimpleSlimefunItem<BlockTicker> implements EnergyNetComponent {
private final int[] border = { 0, 2, 3, 4, 5, 6, 8, 12, 14, 21, 23, 30, 32, 39, 40, 41 };
private final int[] inputSlots = { 19, 28, 25, 34 };
private final int[] headSlots = { 19, 28 };
private final int[] headBorder = { 9, 10, 11, 18, 20, 27, 29, 36, 37, 38 };
private final int[] bodySlots = { 25, 34 };
private final int[] bodyBorder = { 15, 16, 17, 24, 26, 33, 35, 42, 43, 44 };
private int lifetime = 0;
public AbstractEntityAssembler(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(category, item, recipeType, recipe);
new BlockMenuPreset(getID(), item.getImmutableMeta().getDisplayName().orElse("Entity Assembler")) {
@Override
public void init() {
for (int i : border) {
addItem(i, ChestMenuUtils.getBackground(), ChestMenuUtils.getEmptyClickHandler());
}
for (int i : headBorder) {
addItem(i, new CustomItem(getHeadBorder(), " "), ChestMenuUtils.getEmptyClickHandler());
}
for (int i : bodyBorder) {
addItem(i, new CustomItem(getBodyBorder(), " "), ChestMenuUtils.getEmptyClickHandler());
}
constructMenu(this);
}
@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(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);
return false;
});
}
else {
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);
return false;
});
}
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(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));
newInstance(menu, b);
return false;
});
}
@Override
public boolean canOpen(Block b, Player p) {
return p.hasPermission("slimefun.inventory.bypass") || SlimefunPlugin.getProtectionManager().hasPermission(p, b.getLocation(), ProtectableAction.ACCESS_INVENTORIES);
}
@Override
public int[] getSlotsAccessedByItemTransport(ItemTransportFlow flow) {
if (flow == ItemTransportFlow.INSERT) {
return inputSlots;
}
else {
return new int[0];
}
}
@Override
public int[] getSlotsAccessedByItemTransport(DirtyChestMenu menu, ItemTransportFlow flow, ItemStack item) {
if (flow == ItemTransportFlow.INSERT && item != null) {
if (item.getType() == getBody().getType()) {
return bodySlots;
}
if (item.getType() == getHead().getType()) {
return headSlots;
}
}
return new int[0];
}
};
registerBlockHandler(getID(), new SlimefunBlockHandler() {
@Override
public void onPlace(Player p, Block b, SlimefunItem item) {
BlockStorage.addBlockInfo(b, "offset", "3.0");
BlockStorage.addBlockInfo(b, "enabled", String.valueOf(false));
}
@Override
public boolean onBreak(Player p, Block b, SlimefunItem item, UnregisterReason reason) {
if (reason == UnregisterReason.EXPLODE) {
return false;
}
BlockMenu inv = BlockStorage.getInventory(b);
if (inv != null) {
for (int slot : bodySlots) {
if (inv.getItemInSlot(slot) != null) {
b.getWorld().dropItemNaturally(b.getLocation(), inv.getItemInSlot(slot));
inv.replaceExistingItem(slot, null);
}
}
for (int slot : headSlots) {
if (inv.getItemInSlot(slot) != null) {
b.getWorld().dropItemNaturally(b.getLocation(), inv.getItemInSlot(slot));
inv.replaceExistingItem(slot, null);
}
}
}
return true;
}
});
}
@Override
public BlockTicker getItemHandler() {
return new BlockTicker() {
@Override
public void tick(Block b, SlimefunItem sf, Config data) {
if (String.valueOf(false).equals(BlockStorage.getLocationInfo(b.getLocation(), "enabled"))) {
return;
}
if (lifetime % 60 == 0 && ChargableBlock.getCharge(b) >= getEnergyConsumption()) {
BlockMenu menu = BlockStorage.getInventory(b);
boolean hasBody = findResource(menu, getBody(), bodySlots);
boolean hasHead = findResource(menu, getHead(), headSlots);
if (hasBody && hasHead) {
consumeResources(menu);
ChargableBlock.addCharge(b, -getEnergyConsumption());
double offset = Double.parseDouble(BlockStorage.getLocationInfo(b.getLocation(), "offset"));
Slimefun.runSync(() -> {
Location loc = new Location(b.getWorld(), b.getX() + 0.5D, b.getY() + offset, b.getZ() + 0.5D);
b.getWorld().spawnEntity(loc, EntityType.WITHER);
});
}
}
}
@Override
public void uniqueTick() {
lifetime++;
}
@Override
public boolean isSynchronized() {
return false;
}
};
}
private boolean findResource(BlockMenu menu, ItemStack item, int[] slots) {
Material resource = item.getType();
int required = item.getAmount();
int found = 0;
for (int slot : slots) {
if (SlimefunUtils.isItemSimilar(menu.getItemInSlot(slot), new ItemStack(resource), true, false)) {
found += menu.getItemInSlot(slot).getAmount();
if (found > required) {
return true;
}
}
}
return false;
}
private void consumeResources(BlockMenu inv) {
int bodyCount = getBody().getAmount();
int headCount = getHead().getAmount();
for (int slot : bodySlots) {
if (SlimefunUtils.isItemSimilar(inv.getItemInSlot(slot), new ItemStack(getBody().getType()), true, false)) {
int amount = inv.getItemInSlot(slot).getAmount();
if (amount >= bodyCount) {
inv.consumeItem(slot, bodyCount);
break;
}
else {
bodyCount -= amount;
inv.replaceExistingItem(slot, null);
}
}
}
for (int slot : headSlots) {
if (SlimefunUtils.isItemSimilar(inv.getItemInSlot(slot), new ItemStack(getHead().getType()), true, false)) {
int amount = inv.getItemInSlot(slot).getAmount();
if (amount >= headCount) {
inv.consumeItem(slot, headCount);
break;
}
else {
headCount -= amount;
inv.replaceExistingItem(slot, null);
}
}
}
}
protected void constructMenu(BlockMenuPreset preset) {
preset.addItem(1, new CustomItem(getHead(), "&7Head Slot", "", "&rThis Slot accepts the head type"), ChestMenuUtils.getEmptyClickHandler());
preset.addItem(7, new CustomItem(getBody(), "&7Body Slot", "", "&rThis Slot accepts the body type"), ChestMenuUtils.getEmptyClickHandler());
preset.addItem(13, new CustomItem(Material.CLOCK, "&7Cooldown: &b30 Seconds", "", "&rThis Machine takes up to half a Minute to operate", "&rso give it some Time!"), ChestMenuUtils.getEmptyClickHandler());
}
@Override
public EnergyNetComponentType getEnergyComponentType() {
return EnergyNetComponentType.CONSUMER;
}
public abstract int getEnergyConsumption();
public abstract ItemStack getHead();
public abstract ItemStack getBody();
public abstract Material getHeadBorder();
public abstract Material getBodyBorder();
}

View File

@ -0,0 +1,66 @@
package io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines;
import org.bukkit.Material;
import org.bukkit.entity.IronGolem;
import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils;
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset;
/**
* The {@link IronGolemAssembler} is an electrical machine that can automatically spawn
* a {@link IronGolem} if the required ingredients have been provided.
*
* @author TheBusyBiscuit
*
* @see WitherAssembler
*
*/
public class IronGolemAssembler extends AbstractEntityAssembler {
public IronGolemAssembler(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(category, item, recipeType, recipe);
}
@Override
public int getCapacity() {
return 4096;
}
@Override
public int getEnergyConsumption() {
return 2048;
}
@Override
public ItemStack getHead() {
return new ItemStack(Material.PUMPKIN);
}
@Override
public Material getHeadBorder() {
return Material.ORANGE_STAINED_GLASS_PANE;
}
@Override
public ItemStack getBody() {
return new ItemStack(Material.IRON_BLOCK, 4);
}
@Override
public Material getBodyBorder() {
return Material.WHITE_STAINED_GLASS_PANE;
}
@Override
protected void constructMenu(BlockMenuPreset preset) {
preset.addItem(1, new CustomItem(getHead(), "&7Pumpkin Slot", "", "&rThis Slot accepts Pumpkins"), ChestMenuUtils.getEmptyClickHandler());
preset.addItem(7, new CustomItem(getBody(), "&7Iron Block Slot", "", "&rThis Slot accepts Iron Blocks"), ChestMenuUtils.getEmptyClickHandler());
preset.addItem(13, new CustomItem(Material.CLOCK, "&7Cooldown: &b30 Seconds", "", "&rThis Machine takes up to half a Minute to operate", "&rso give it some Time!"), ChestMenuUtils.getEmptyClickHandler());
}
}

View File

@ -1,196 +1,29 @@
package io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.entity.Wither;
import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
import io.github.thebusybiscuit.cscorelib2.math.DoubleHandler;
import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction;
import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetComponent;
import io.github.thebusybiscuit.slimefun4.core.networks.energy.EnergyNetComponentType;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils;
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config;
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.Objects.SlimefunBlockHandler;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.UnregisterReason;
import me.mrCookieSlime.Slimefun.Objects.handlers.BlockTicker;
import me.mrCookieSlime.Slimefun.api.BlockStorage;
import me.mrCookieSlime.Slimefun.api.Slimefun;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
import me.mrCookieSlime.Slimefun.api.energy.ChargableBlock;
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu;
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset;
import me.mrCookieSlime.Slimefun.api.inventory.DirtyChestMenu;
import me.mrCookieSlime.Slimefun.api.item_transport.ItemTransportFlow;
/**
* The {@link WitherAssembler} is an electrical machine that can automatically spawn
* a {@link Wither} if the required ingredients have been provided.
*
* @author TheBusyBiscuit
*
* @see IronGolemAssembler
*
*/
public class WitherAssembler extends SimpleSlimefunItem<BlockTicker> implements EnergyNetComponent {
private static final int ENERGY_CONSUMPTION = 4096;
private final int[] border = { 0, 2, 3, 4, 5, 6, 8, 12, 14, 21, 23, 30, 32, 39, 40, 41 };
private final int[] skullBorder = { 9, 10, 11, 18, 20, 27, 29, 36, 37, 38 };
private final int[] sandBorder = { 15, 16, 17, 24, 26, 33, 35, 42, 43, 44 };
private int lifetime = 0;
public class WitherAssembler extends AbstractEntityAssembler {
public WitherAssembler(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(category, item, recipeType, recipe);
new BlockMenuPreset(getID(), "&5Wither Assembler") {
@Override
public void init() {
constructMenu(this);
}
@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(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);
return false;
});
}
else {
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);
return false;
});
}
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(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));
newInstance(menu, b);
return false;
});
}
@Override
public boolean canOpen(Block b, Player p) {
return p.hasPermission("slimefun.inventory.bypass") || SlimefunPlugin.getProtectionManager().hasPermission(p, b.getLocation(), ProtectableAction.ACCESS_INVENTORIES);
}
@Override
public int[] getSlotsAccessedByItemTransport(ItemTransportFlow flow) {
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 && item != null) {
if (item.getType() == Material.SOUL_SAND) {
return getSoulSandSlots();
}
if (item.getType() == Material.WITHER_SKELETON_SKULL) {
return getWitherSkullSlots();
}
}
return new int[0];
}
};
registerBlockHandler(getID(), new SlimefunBlockHandler() {
@Override
public void onPlace(Player p, Block b, SlimefunItem item) {
BlockStorage.addBlockInfo(b, "offset", "3.0");
BlockStorage.addBlockInfo(b, "enabled", String.valueOf(false));
}
@Override
public boolean onBreak(Player p, Block b, SlimefunItem item, UnregisterReason reason) {
if (reason == UnregisterReason.EXPLODE) {
return false;
}
BlockMenu inv = BlockStorage.getInventory(b);
if (inv != null) {
for (int slot : getSoulSandSlots()) {
if (inv.getItemInSlot(slot) != null) {
b.getWorld().dropItemNaturally(b.getLocation(), inv.getItemInSlot(slot));
inv.replaceExistingItem(slot, null);
}
}
for (int slot : getWitherSkullSlots()) {
if (inv.getItemInSlot(slot) != null) {
b.getWorld().dropItemNaturally(b.getLocation(), inv.getItemInSlot(slot));
inv.replaceExistingItem(slot, null);
}
}
}
return true;
}
});
}
private void constructMenu(BlockMenuPreset preset) {
for (int i : border) {
preset.addItem(i, ChestMenuUtils.getBackground(), ChestMenuUtils.getEmptyClickHandler());
}
for (int i : skullBorder) {
preset.addItem(i, new CustomItem(Material.BLACK_STAINED_GLASS_PANE, " "), ChestMenuUtils.getEmptyClickHandler());
}
for (int i : sandBorder) {
preset.addItem(i, new CustomItem(Material.BROWN_STAINED_GLASS_PANE, " "), ChestMenuUtils.getEmptyClickHandler());
}
preset.addItem(1, new CustomItem(Material.WITHER_SKELETON_SKULL, "&7Wither Skull Slot", "", "&rThis Slot accepts Wither Skeleton Skulls"), ChestMenuUtils.getEmptyClickHandler());
preset.addItem(7, new CustomItem(Material.SOUL_SAND, "&7Soul Sand Slot", "", "&rThis Slot accepts Soul Sand"), ChestMenuUtils.getEmptyClickHandler());
preset.addItem(13, new CustomItem(Material.CLOCK, "&7Cooldown: &b30 Seconds", "", "&rThis Machine takes up to half a Minute to operate", "&rso give it some Time!"), ChestMenuUtils.getEmptyClickHandler());
}
public int[] getInputSlots() {
return new int[] { 19, 28, 25, 34 };
}
public int[] getWitherSkullSlots() {
return new int[] { 19, 28 };
}
public int[] getSoulSandSlots() {
return new int[] { 25, 34 };
}
@Override
public EnergyNetComponentType getEnergyComponentType() {
return EnergyNetComponentType.CONSUMER;
}
@Override
@ -199,93 +32,35 @@ public class WitherAssembler extends SimpleSlimefunItem<BlockTicker> implements
}
@Override
public BlockTicker getItemHandler() {
return new BlockTicker() {
@Override
public void tick(Block b, SlimefunItem sf, Config data) {
if (String.valueOf(false).equals(BlockStorage.getLocationInfo(b.getLocation(), "enabled"))) {
return;
}
if (lifetime % 60 == 0 && ChargableBlock.getCharge(b) >= ENERGY_CONSUMPTION) {
BlockMenu menu = BlockStorage.getInventory(b);
boolean soulsand = findResource(menu, Material.SOUL_SAND, 4, getSoulSandSlots());
boolean skulls = findResource(menu, Material.WITHER_SKELETON_SKULL, 3, getWitherSkullSlots());
if (soulsand && skulls) {
consumeResources(menu);
ChargableBlock.addCharge(b, -ENERGY_CONSUMPTION);
double offset = Double.parseDouble(BlockStorage.getLocationInfo(b.getLocation(), "offset"));
Slimefun.runSync(() -> b.getWorld().spawnEntity(new Location(b.getWorld(), b.getX() + 0.5D, b.getY() + offset, b.getZ() + 0.5D), EntityType.WITHER));
}
}
}
@Override
public void uniqueTick() {
lifetime++;
}
@Override
public boolean isSynchronized() {
return false;
}
};
public int getEnergyConsumption() {
return 4096;
}
private boolean findResource(BlockMenu menu, Material resource, int required, int[] slots) {
int found = 0;
for (int slot : slots) {
if (SlimefunUtils.isItemSimilar(menu.getItemInSlot(slot), new ItemStack(resource), true, false)) {
found += menu.getItemInSlot(slot).getAmount();
if (found > required) {
return true;
}
}
}
return false;
@Override
public ItemStack getHead() {
return new ItemStack(Material.WITHER_SKELETON_SKULL, 3);
}
private void consumeResources(BlockMenu inv) {
int soulsand = 4;
int skulls = 3;
@Override
public Material getHeadBorder() {
return Material.BLACK_STAINED_GLASS_PANE;
}
for (int slot : getSoulSandSlots()) {
if (SlimefunUtils.isItemSimilar(inv.getItemInSlot(slot), new ItemStack(Material.SOUL_SAND), true, false)) {
int amount = inv.getItemInSlot(slot).getAmount();
@Override
public ItemStack getBody() {
return new ItemStack(Material.SOUL_SAND, 4);
}
if (amount >= soulsand) {
inv.consumeItem(slot, soulsand);
break;
}
else {
soulsand -= amount;
inv.replaceExistingItem(slot, null);
}
}
}
@Override
public Material getBodyBorder() {
return Material.BROWN_STAINED_GLASS_PANE;
}
for (int slot : getWitherSkullSlots()) {
if (SlimefunUtils.isItemSimilar(inv.getItemInSlot(slot), new ItemStack(Material.WITHER_SKELETON_SKULL), true, false)) {
int amount = inv.getItemInSlot(slot).getAmount();
if (amount >= skulls) {
inv.consumeItem(slot, skulls);
break;
}
else {
skulls -= amount;
inv.replaceExistingItem(slot, null);
}
}
}
@Override
protected void constructMenu(BlockMenuPreset preset) {
preset.addItem(1, new CustomItem(getHead(), "&7Wither Skeleton Skull Slot", "", "&rThis Slot accepts Wither Skeleton Skulls"), ChestMenuUtils.getEmptyClickHandler());
preset.addItem(7, new CustomItem(getBody(), "&7Soul Sand Slot", "", "&rThis Slot accepts Soul Sand"), ChestMenuUtils.getEmptyClickHandler());
preset.addItem(13, new CustomItem(Material.CLOCK, "&7Cooldown: &b30 Seconds", "", "&rThis Machine takes up to half a Minute to operate", "&rso give it some Time!"), ChestMenuUtils.getEmptyClickHandler());
}
}

View File

@ -20,7 +20,7 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
*/
public class MeatJerky extends SimpleSlimefunItem<ItemConsumptionHandler> {
private ItemSetting<Integer> saturation = new ItemSetting<>("saturation-level", 6);
private final ItemSetting<Integer> saturation = new ItemSetting<>("saturation-level", 6);
public MeatJerky(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(category, item, recipeType, recipe);

View File

@ -24,9 +24,7 @@ public class PortableGEOScanner extends SimpleSlimefunItem<ItemUseHandler> {
Optional<Block> block = e.getClickedBlock();
e.cancel();
if (block.isPresent()) {
SlimefunPlugin.getGPSNetwork().getResourceManager().scan(e.getPlayer(), block.get(), 0);
}
block.ifPresent(value -> SlimefunPlugin.getGPSNetwork().getResourceManager().scan(e.getPlayer(), value, 0));
};
}

View File

@ -30,8 +30,8 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
*/
abstract class AbstractSmeltery extends MultiBlockMachine {
public AbstractSmeltery(Category category, SlimefunItemStack item, ItemStack[] recipe, ItemStack[] machineRecipes, BlockFace trigger) {
super(category, item, recipe, machineRecipes, trigger);
public AbstractSmeltery(Category category, SlimefunItemStack item, ItemStack[] recipe, BlockFace trigger) {
super(category, item, recipe, trigger);
}
@Override

View File

@ -26,7 +26,7 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
public class ArmorForge extends MultiBlockMachine {
public ArmorForge(Category category, SlimefunItemStack item) {
super(category, item, new ItemStack[] { null, null, null, null, new ItemStack(Material.ANVIL), null, null, new CustomItem(Material.DISPENSER, "Dispenser (Facing up)"), null }, new ItemStack[0], BlockFace.SELF);
super(category, item, new ItemStack[] { null, null, null, null, new ItemStack(Material.ANVIL), null, null, new CustomItem(Material.DISPENSER, "Dispenser (Facing up)"), null }, BlockFace.SELF);
}
@Override

View File

@ -29,7 +29,7 @@ public class AutomatedPanningMachine extends MultiBlockMachine {
private final GoldPan netherGoldPan = (GoldPan) SlimefunItems.NETHER_GOLD_PAN.getItem();
public AutomatedPanningMachine(Category category, SlimefunItemStack item) {
super(category, item, new ItemStack[] { null, null, null, null, new ItemStack(Material.OAK_TRAPDOOR), null, null, new ItemStack(Material.CAULDRON), null }, new ItemStack[0], BlockFace.SELF);
super(category, item, new ItemStack[] { null, null, null, null, new ItemStack(Material.OAK_TRAPDOOR), null, null, new ItemStack(Material.CAULDRON), null }, BlockFace.SELF);
}
@Override

View File

@ -26,8 +26,8 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
abstract class BackpackCrafter extends MultiBlockMachine {
public BackpackCrafter(Category category, SlimefunItemStack item, ItemStack[] recipe, ItemStack[] machineRecipes, BlockFace trigger) {
super(category, item, recipe, machineRecipes, trigger);
public BackpackCrafter(Category category, SlimefunItemStack item, ItemStack[] recipe, BlockFace trigger) {
super(category, item, recipe, trigger);
}
protected Inventory createVirtualInventory(Inventory inv) {
@ -92,9 +92,7 @@ abstract class BackpackCrafter extends MultiBlockMachine {
PlayerProfile.fromUUID(UUID.fromString(idSplit[0]), profile -> {
Optional<PlayerBackpack> optional = profile.getBackpack(Integer.parseInt(idSplit[1]));
if (optional.isPresent()) {
optional.get().setSize(size);
}
optional.ifPresent(playerBackpack -> playerBackpack.setSize(size));
});
return Optional.of(id);

View File

@ -27,7 +27,16 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
public class Compressor extends MultiBlockMachine {
public Compressor(Category category, SlimefunItemStack item) {
super(category, item, new ItemStack[] { null, null, null, null, new ItemStack(Material.NETHER_BRICK_FENCE), null, new ItemStack(Material.PISTON), new CustomItem(Material.DISPENSER, "Dispenser (Facing up)"), new ItemStack(Material.PISTON) }, new ItemStack[] { new CustomItem(SlimefunItems.STONE_CHUNK, 4), new ItemStack(Material.COBBLESTONE), new ItemStack(Material.FLINT, 8), new ItemStack(Material.COBBLESTONE) }, BlockFace.SELF);
super(category, item, new ItemStack[] { null, null, null, null, new ItemStack(Material.NETHER_BRICK_FENCE), null, new ItemStack(Material.PISTON), new CustomItem(Material.DISPENSER, "Dispenser (Facing up)"), new ItemStack(Material.PISTON) }, BlockFace.SELF);
}
@Override
protected void registerDefaultRecipes(List<ItemStack> recipes) {
recipes.add(new SlimefunItemStack(SlimefunItems.STONE_CHUNK, 4));
recipes.add(new ItemStack(Material.COBBLESTONE));
recipes.add(new ItemStack(Material.FLINT, 8));
recipes.add(new ItemStack(Material.COBBLESTONE));
}
@Override

View File

@ -26,7 +26,7 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
public class EnhancedCraftingTable extends BackpackCrafter {
public EnhancedCraftingTable(Category category, SlimefunItemStack item) {
super(category, item, new ItemStack[] { null, null, null, null, new ItemStack(Material.CRAFTING_TABLE), null, null, new ItemStack(Material.DISPENSER), null }, new ItemStack[0], BlockFace.SELF);
super(category, item, new ItemStack[] { null, null, null, null, new ItemStack(Material.CRAFTING_TABLE), null, null, new ItemStack(Material.DISPENSER), null }, BlockFace.SELF);
}
@Override

View File

@ -26,7 +26,52 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
public class GrindStone extends MultiBlockMachine {
public GrindStone(Category category, SlimefunItemStack item) {
super(category, item, new ItemStack[] { null, null, null, null, new ItemStack(Material.OAK_FENCE), null, null, new CustomItem(Material.DISPENSER, "Dispenser (Facing up)"), null }, new ItemStack[] { new ItemStack(Material.BLAZE_ROD), new ItemStack(Material.BLAZE_POWDER, 4), new ItemStack(Material.BONE), new ItemStack(Material.BONE_MEAL, 4), new ItemStack(Material.GRAVEL), new ItemStack(Material.FLINT), new ItemStack(Material.ENDER_EYE), new CustomItem(SlimefunItems.ENDER_LUMP_1, 2), new ItemStack(Material.COBBLESTONE), new ItemStack(Material.GRAVEL), new ItemStack(Material.ANDESITE), new ItemStack(Material.GRAVEL), new ItemStack(Material.DIORITE), new ItemStack(Material.GRAVEL), new ItemStack(Material.GRANITE), new ItemStack(Material.GRAVEL), new ItemStack(Material.DIRT), SlimefunItems.STONE_CHUNK, new ItemStack(Material.SANDSTONE), new ItemStack(Material.SAND, 4), new ItemStack(Material.RED_SANDSTONE), new ItemStack(Material.RED_SAND, 4), new ItemStack(Material.PRISMARINE_BRICKS), new ItemStack(Material.PRISMARINE, 2), new ItemStack(Material.PRISMARINE), new ItemStack(Material.PRISMARINE_SHARD, 4) }, BlockFace.SELF);
super(category, item, new ItemStack[] { null, null, null, null, new ItemStack(Material.OAK_FENCE), null, null, new CustomItem(Material.DISPENSER, "Dispenser (Facing up)"), null }, BlockFace.SELF);
}
@Override
protected void registerDefaultRecipes(List<ItemStack> recipes) {
recipes.add(new ItemStack(Material.BLAZE_ROD));
recipes.add(new ItemStack(Material.BLAZE_POWDER, 4));
recipes.add(new ItemStack(Material.BONE));
recipes.add(new ItemStack(Material.BONE_MEAL, 4));
recipes.add(new ItemStack(Material.BONE_BLOCK));
recipes.add(new ItemStack(Material.BONE_MEAL, 9));
recipes.add(new ItemStack(Material.GRAVEL));
recipes.add(new ItemStack(Material.FLINT));
recipes.add(new ItemStack(Material.ENDER_EYE));
recipes.add(new SlimefunItemStack(SlimefunItems.ENDER_LUMP_1, 2));
recipes.add(new ItemStack(Material.COBBLESTONE));
recipes.add(new ItemStack(Material.GRAVEL));
recipes.add(new ItemStack(Material.ANDESITE));
recipes.add(new ItemStack(Material.GRAVEL));
recipes.add(new ItemStack(Material.DIORITE));
recipes.add(new ItemStack(Material.GRAVEL));
recipes.add(new ItemStack(Material.GRANITE));
recipes.add(new ItemStack(Material.GRAVEL));
recipes.add(new ItemStack(Material.DIRT));
recipes.add(SlimefunItems.STONE_CHUNK);
recipes.add(new ItemStack(Material.SANDSTONE));
recipes.add(new ItemStack(Material.SAND, 4));
recipes.add(new ItemStack(Material.RED_SANDSTONE));
recipes.add(new ItemStack(Material.RED_SAND, 4));
recipes.add(new ItemStack(Material.PRISMARINE_BRICKS));
recipes.add(new ItemStack(Material.PRISMARINE, 2));
recipes.add(new ItemStack(Material.PRISMARINE));
recipes.add(new ItemStack(Material.PRISMARINE_SHARD, 4));
}
@Override

View File

@ -26,7 +26,7 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
public class Juicer extends MultiBlockMachine {
public Juicer(Category category, SlimefunItemStack item) {
super(category, item, new ItemStack[] { null, new ItemStack(Material.GLASS), null, null, new ItemStack(Material.NETHER_BRICK_FENCE), null, null, new CustomItem(Material.DISPENSER, "Dispenser (Facing up)"), null }, new ItemStack[0], BlockFace.SELF);
super(category, item, new ItemStack[] { null, new ItemStack(Material.GLASS), null, null, new ItemStack(Material.NETHER_BRICK_FENCE), null, null, new CustomItem(Material.DISPENSER, "Dispenser (Facing up)"), null }, BlockFace.SELF);
}
@Override

View File

@ -27,7 +27,7 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
public class MagicWorkbench extends BackpackCrafter {
public MagicWorkbench(Category category, SlimefunItemStack item) {
super(category, item, new ItemStack[] { null, null, null, null, null, null, new ItemStack(Material.BOOKSHELF), new ItemStack(Material.CRAFTING_TABLE), new ItemStack(Material.DISPENSER) }, new ItemStack[0], BlockFace.UP);
super(category, item, new ItemStack[] { null, null, null, null, null, null, new ItemStack(Material.BOOKSHELF), new ItemStack(Material.CRAFTING_TABLE), new ItemStack(Material.DISPENSER) }, BlockFace.UP);
}
@Override

View File

@ -18,7 +18,7 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
public class MakeshiftSmeltery extends AbstractSmeltery {
public MakeshiftSmeltery(Category category, SlimefunItemStack item) {
super(category, item, new ItemStack[] { null, new ItemStack(Material.OAK_FENCE), null, new ItemStack(Material.BRICKS), new CustomItem(Material.DISPENSER, "Dispenser (Facing up)"), new ItemStack(Material.BRICKS), null, new ItemStack(Material.FLINT_AND_STEEL), null }, new ItemStack[0], BlockFace.DOWN);
super(category, item, new ItemStack[] { null, new ItemStack(Material.OAK_FENCE), null, new ItemStack(Material.BRICKS), new CustomItem(Material.DISPENSER, "Dispenser (Facing up)"), new ItemStack(Material.BRICKS), null, new ItemStack(Material.FLINT_AND_STEEL), null }, BlockFace.DOWN);
}
@Override

View File

@ -32,11 +32,26 @@ public class OreCrusher extends MultiBlockMachine {
private final DoubleOreSetting doubleOres = new DoubleOreSetting();
public OreCrusher(Category category, SlimefunItemStack item) {
super(category, item, new ItemStack[] { null, null, null, null, new ItemStack(Material.NETHER_BRICK_FENCE), null, new ItemStack(Material.IRON_BARS), new CustomItem(Material.DISPENSER, "Dispenser (Facing up)"), new ItemStack(Material.IRON_BARS) }, new ItemStack[] { new ItemStack(Material.COBBLESTONE, 8), new ItemStack(Material.SAND, 1), SlimefunItems.GOLD_4K, SlimefunItems.GOLD_DUST, new ItemStack(Material.GRAVEL), new ItemStack(Material.SAND), new ItemStack(Material.MAGMA_BLOCK, 4), SlimefunItems.SULFATE }, BlockFace.SELF);
super(category, item, new ItemStack[] { null, null, null, null, new ItemStack(Material.NETHER_BRICK_FENCE), null, new ItemStack(Material.IRON_BARS), new CustomItem(Material.DISPENSER, "Dispenser (Facing up)"), new ItemStack(Material.IRON_BARS) }, BlockFace.SELF);
addItemSetting(doubleOres);
}
@Override
protected void registerDefaultRecipes(List<ItemStack> recipes) {
recipes.add(new ItemStack(Material.COBBLESTONE, 8));
recipes.add(new ItemStack(Material.SAND, 1));
recipes.add(SlimefunItems.GOLD_4K);
recipes.add(SlimefunItems.GOLD_DUST);
recipes.add(new ItemStack(Material.GRAVEL));
recipes.add(new ItemStack(Material.SAND));
recipes.add(new ItemStack(Material.MAGMA_BLOCK, 4));
recipes.add(SlimefunItems.SULFATE);
}
public boolean isOreDoublingEnabled() {
return doubleOres.getValue();
}

View File

@ -29,7 +29,7 @@ public class OreWasher extends MultiBlockMachine {
private final ItemStack[] dusts;
public OreWasher(Category category, SlimefunItemStack item) {
super(category, item, new ItemStack[] { null, new ItemStack(Material.DISPENSER), null, null, new ItemStack(Material.OAK_FENCE), null, null, new ItemStack(Material.CAULDRON), null }, new ItemStack[0], BlockFace.SELF);
super(category, item, new ItemStack[] { null, new ItemStack(Material.DISPENSER), null, null, new ItemStack(Material.OAK_FENCE), null, null, new ItemStack(Material.CAULDRON), null }, BlockFace.SELF);
legacyMode = SlimefunPlugin.getCfg().getBoolean("options.legacy-ore-washer");
dusts = new ItemStack[] { SlimefunItems.IRON_DUST, SlimefunItems.GOLD_DUST, SlimefunItems.COPPER_DUST, SlimefunItems.TIN_DUST, SlimefunItems.ZINC_DUST, SlimefunItems.ALUMINUM_DUST, SlimefunItems.MAGNESIUM_DUST, SlimefunItems.LEAD_DUST, SlimefunItems.SILVER_DUST };

View File

@ -29,7 +29,7 @@ public class PressureChamber extends MultiBlockMachine {
public PressureChamber(Category category, SlimefunItemStack item) {
super(category, item, new ItemStack[] { SlimefunPlugin.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_14) ? new ItemStack(Material.SMOOTH_STONE_SLAB) : new ItemStack(Material.STONE_SLAB), new CustomItem(Material.DISPENSER, "Dispenser (Facing down)"), SlimefunPlugin.getMinecraftVersion()
.isAtLeast(MinecraftVersion.MINECRAFT_1_14) ? new ItemStack(Material.SMOOTH_STONE_SLAB) : new ItemStack(Material.STONE_SLAB), new ItemStack(Material.PISTON), new ItemStack(Material.GLASS), new ItemStack(Material.PISTON), new ItemStack(Material.PISTON), new ItemStack(Material.CAULDRON), new ItemStack(Material.PISTON) }, new ItemStack[0], BlockFace.UP);
.isAtLeast(MinecraftVersion.MINECRAFT_1_14) ? new ItemStack(Material.SMOOTH_STONE_SLAB) : new ItemStack(Material.STONE_SLAB), new ItemStack(Material.PISTON), new ItemStack(Material.GLASS), new ItemStack(Material.PISTON), new ItemStack(Material.PISTON), new ItemStack(Material.CAULDRON), new ItemStack(Material.PISTON) }, BlockFace.UP);
}
@Override

View File

@ -34,11 +34,17 @@ public class Smeltery extends AbstractSmeltery {
private final ItemSetting<Integer> fireBreakingChance = new ItemSetting<>("fire-breaking-chance", 34);
public Smeltery(Category category, SlimefunItemStack item) {
super(category, item, new ItemStack[] { null, new ItemStack(Material.NETHER_BRICK_FENCE), null, new ItemStack(Material.NETHER_BRICKS), new CustomItem(Material.DISPENSER, "Dispenser (Facing up)"), new ItemStack(Material.NETHER_BRICKS), null, new ItemStack(Material.FLINT_AND_STEEL), null }, new ItemStack[] { SlimefunItems.IRON_DUST, new ItemStack(Material.IRON_INGOT) }, BlockFace.DOWN);
super(category, item, new ItemStack[] { null, new ItemStack(Material.NETHER_BRICK_FENCE), null, new ItemStack(Material.NETHER_BRICKS), new CustomItem(Material.DISPENSER, "Dispenser (Facing up)"), new ItemStack(Material.NETHER_BRICKS), null, new ItemStack(Material.FLINT_AND_STEEL), null }, BlockFace.DOWN);
addItemSetting(fireBreakingChance);
}
@Override
protected void registerDefaultRecipes(List<ItemStack> recipes) {
recipes.add(SlimefunItems.IRON_DUST);
recipes.add(new ItemStack(Material.IRON_INGOT));
}
@Override
public List<ItemStack> getDisplayRecipes() {
List<ItemStack> items = new ArrayList<>();

View File

@ -36,7 +36,7 @@ public class TableSaw extends MultiBlockMachine {
private final List<ItemStack> displayedRecipes = new ArrayList<>();
public TableSaw(Category category, SlimefunItemStack item) {
super(category, item, new ItemStack[] { null, null, null, new ItemStack(Material.SMOOTH_STONE_SLAB), new ItemStack(Material.STONECUTTER), new ItemStack(Material.SMOOTH_STONE_SLAB), null, new ItemStack(Material.IRON_BLOCK), null }, new ItemStack[0], BlockFace.SELF);
super(category, item, new ItemStack[] { null, null, null, new ItemStack(Material.SMOOTH_STONE_SLAB), new ItemStack(Material.STONECUTTER), new ItemStack(Material.SMOOTH_STONE_SLAB), null, new ItemStack(Material.IRON_BLOCK), null }, BlockFace.SELF);
for (Material log : Tag.LOGS.getValues()) {
Optional<Material> planks = MaterialConverter.getPlanksFromLog(log);

View File

@ -49,7 +49,7 @@ public class IndustrialMiner extends MultiBlockMachine {
private final boolean silkTouch;
public IndustrialMiner(Category category, SlimefunItemStack item, Material baseMaterial, boolean silkTouch, int range) {
super(category, item, new ItemStack[] { null, null, null, new CustomItem(Material.PISTON, "Piston (facing up)"), new ItemStack(Material.CHEST), new CustomItem(Material.PISTON, "Piston (facing up)"), new ItemStack(baseMaterial), new ItemStack(SlimefunPlugin.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_14) ? Material.BLAST_FURNACE : Material.FURNACE), new ItemStack(baseMaterial) }, new ItemStack[0], BlockFace.UP);
super(category, item, new ItemStack[] { null, null, null, new CustomItem(Material.PISTON, "Piston (facing up)"), new ItemStack(Material.CHEST), new CustomItem(Material.PISTON, "Piston (facing up)"), new ItemStack(baseMaterial), new ItemStack(SlimefunPlugin.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_14) ? Material.BLAST_FURNACE : Material.FURNACE), new ItemStack(baseMaterial) }, BlockFace.UP);
this.range = range;
this.silkTouch = silkTouch;

View File

@ -2,17 +2,20 @@ package io.github.thebusybiscuit.slimefun4.implementation.listeners;
import java.util.Optional;
import org.bukkit.Material;
import org.bukkit.block.BlockState;
import org.bukkit.block.Furnace;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.FurnaceBurnEvent;
import org.bukkit.event.inventory.FurnaceSmeltEvent;
import org.bukkit.inventory.FurnaceInventory;
import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.items.blocks.EnhancedFurnace;
import io.papermc.lib.PaperLib;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.api.BlockStorage;
@ -33,31 +36,44 @@ public class EnhancedFurnaceListener implements Listener {
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onFuelBurn(FurnaceBurnEvent e) {
if (e.getBlock().getType() != Material.FURNACE) {
// We don't care about Smokers, Blast Furnaces and all that fancy stuff
return;
}
SlimefunItem furnace = BlockStorage.check(e.getBlock());
if (furnace instanceof EnhancedFurnace && ((EnhancedFurnace) furnace).getFuelEfficiency() > 0) {
int burnTime = e.getBurnTime();
int newBurnTime = ((EnhancedFurnace) furnace).getFuelEfficiency() * burnTime;
e.setBurnTime(Math.min(newBurnTime, Short.MAX_VALUE));
e.setBurnTime(Math.min(newBurnTime, Short.MAX_VALUE - 1));
}
}
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onItemSmelt(FurnaceSmeltEvent e) {
if (e.getBlock().getType() != Material.FURNACE) {
// We don't care about Smokers, Blast Furnaces and all that fancy stuff
return;
}
SlimefunItem sfItem = BlockStorage.check(e.getBlock());
if (sfItem instanceof EnhancedFurnace) {
Furnace furnace = (Furnace) e.getBlock().getState();
int amount = furnace.getInventory().getSmelting().getType().toString().endsWith("_ORE") ? ((EnhancedFurnace) sfItem).getOutput() : 1;
Optional<ItemStack> result = Optional.ofNullable(furnace.getInventory().getResult());
BlockState state = PaperLib.getBlockState(e.getBlock(), false).getState();
if (!result.isPresent()) {
result = SlimefunPlugin.getMinecraftRecipeService().getFurnaceOutput(furnace.getInventory().getSmelting());
}
if (state instanceof Furnace) {
FurnaceInventory inventory = ((Furnace) state).getInventory();
int amount = inventory.getSmelting().getType().toString().endsWith("_ORE") ? ((EnhancedFurnace) sfItem).getOutput() : 1;
Optional<ItemStack> result = SlimefunPlugin.getMinecraftRecipeService().getFurnaceOutput(inventory.getSmelting());
if (result.isPresent()) {
ItemStack item = result.get();
furnace.getInventory().setResult(new CustomItem(item, Math.min(item.getAmount() + amount, item.getMaxStackSize())));
if (result.isPresent()) {
ItemStack item = result.get();
int previous = inventory.getResult() != null ? inventory.getResult().getAmount() : 0;
amount = Math.min(item.getMaxStackSize() - previous, amount);
e.setResult(new ItemStack(item.getType(), amount));
}
}
}
}

View File

@ -14,9 +14,20 @@ import io.github.thebusybiscuit.slimefun4.core.attributes.RandomMobDrop;
import io.github.thebusybiscuit.slimefun4.core.handlers.EntityKillHandler;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.items.misc.BasicCircuitBoard;
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.api.Slimefun;
/**
* This {@link Listener} is responsible for handling any custom mob drops.
* These drops can also be randomized using the interface {@link RandomMobDrop}, otherwise
* they will be handled via {@link RecipeType}.
*
* @author TheBusyBiscuit
*
* @see RandomMobDrop
*
*/
public class MobDropListener implements Listener {
public MobDropListener(SlimefunPlugin plugin) {
@ -29,7 +40,7 @@ public class MobDropListener implements Listener {
Player p = e.getEntity().getKiller();
ItemStack item = p.getInventory().getItemInMainHand();
Set<ItemStack> customDrops = SlimefunPlugin.getRegistry().getMobDrops(e.getEntityType());
Set<ItemStack> customDrops = SlimefunPlugin.getRegistry().getMobDrops().get(e.getEntityType());
if (customDrops != null && !customDrops.isEmpty()) {
for (ItemStack drop : customDrops) {

View File

@ -31,9 +31,7 @@ public class PlayerProfileListener implements Listener {
Optional<PlayerProfile> profile = PlayerProfile.find(e.getPlayer());
// if we still have a profile of this Player in memory, delete it
if (profile.isPresent()) {
profile.get().markForDeletion();
}
profile.ifPresent(PlayerProfile::markForDeletion);
}
@EventHandler(ignoreCancelled = true)
@ -41,9 +39,7 @@ public class PlayerProfileListener implements Listener {
Optional<PlayerProfile> profile = PlayerProfile.find(e.getPlayer());
// if we still have a profile of this Player in memory, delete it
if (profile.isPresent()) {
profile.get().markForDeletion();
}
profile.ifPresent(PlayerProfile::markForDeletion);
}
}

View File

@ -270,6 +270,7 @@ public final class ResearchSetup {
register("enchantment_rune", 259, "Ancient Enchanting", 24, SlimefunItems.MAGICAL_GLASS, SlimefunItems.ENCHANTMENT_RUNE);
register("lead_clothing", 260, "Lead Clothing", 14, SlimefunItems.REINFORCED_CLOTH);
register("tape_measure", 261, "Tape Measure", 7, SlimefunItems.TAPE_MEASURE);
register("iron_golem_assembler", 262, "Automated Iron Golems", 30, SlimefunItems.IRON_GOLEM_ASSEMBLER);
}
private static void register(String key, int id, String name, int defaultCost, ItemStack... items) {

View File

@ -97,6 +97,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.FoodFabricator;
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.Freezer;
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.HeatedPressureChamber;
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.IronGolemAssembler;
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.Refinery;
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.TreeGrowthAccelerator;
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.WitherAssembler;
@ -3223,6 +3224,10 @@ public final class SlimefunItemSetup {
}.register(plugin);
new IronGolemAssembler(categories.electricity, SlimefunItems.IRON_GOLEM_ASSEMBLER, RecipeType.ENHANCED_CRAFTING_TABLE,
new ItemStack[] {SlimefunItems.BLISTERING_INGOT_3, SlimefunItems.ADVANCED_CIRCUIT_BOARD, SlimefunItems.BLISTERING_INGOT_3, new ItemStack(Material.IRON_BLOCK), SlimefunItems.ANDROID_MEMORY_CORE, new ItemStack(Material.IRON_BLOCK), SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.REINFORCED_ALLOY_INGOT, SlimefunItems.CARBONADO_EDGED_CAPACITOR})
.register(plugin);
new WitherAssembler(categories.electricity, SlimefunItems.WITHER_ASSEMBLER, RecipeType.ENHANCED_CRAFTING_TABLE,
new ItemStack[] {SlimefunItems.BLISTERING_INGOT_3, new ItemStack(Material.NETHER_STAR), SlimefunItems.BLISTERING_INGOT_3, SlimefunItems.WITHER_PROOF_OBSIDIAN, SlimefunItems.ANDROID_MEMORY_CORE, SlimefunItems.WITHER_PROOF_OBSIDIAN, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.REINFORCED_ALLOY_INGOT, SlimefunItems.CARBONADO_EDGED_CAPACITOR})
.register(plugin);

View File

@ -77,7 +77,8 @@ public class ArmorTask implements Runnable {
if (armorpiece.hasDiverged(item)) {
SlimefunItem sfItem = SlimefunItem.getByItem(item);
if (!(sfItem instanceof SlimefunArmorPiece) || !Slimefun.hasUnlocked(p, sfItem, true)) {
if (!(sfItem instanceof SlimefunArmorPiece)) {
// If it isn't actually Armor, then we won't care about it.
sfItem = null;
}
@ -86,9 +87,13 @@ public class ArmorTask implements Runnable {
if (item != null && armorpiece.getItem().isPresent()) {
Slimefun.runSync(() -> {
for (PotionEffect effect : armorpiece.getItem().get().getPotionEffects()) {
p.removePotionEffect(effect.getType());
p.addPotionEffect(effect);
SlimefunArmorPiece slimefunArmor = armorpiece.getItem().get();
if (Slimefun.hasUnlocked(p, slimefunArmor, true)) {
for (PotionEffect effect : slimefunArmor.getPotionEffects()) {
p.removePotionEffect(effect.getType());
p.addPotionEffect(effect);
}
}
});
}

View File

@ -74,7 +74,7 @@ public final class NumberUtils {
}
String number = roundDecimalNumber(nanoseconds / 1000000.0);
String[] parts = PatternUtils.NUMBER_SEPERATOR.split(number);
String[] parts = PatternUtils.NUMBER_SEPARATOR.split(number);
if (parts.length == 1) {
return parts[0] + "ms";

View File

@ -26,6 +26,5 @@ public final class PatternUtils {
public static final Pattern ALPHANUMERIC = Pattern.compile("[A-Fa-f0-9]+");
public static final Pattern NUMERIC = Pattern.compile("[0-9]+");
public static final Pattern NUMBER_SEPERATOR = Pattern.compile(",|\\.");
public static final Pattern NUMBER_SEPARATOR = Pattern.compile("[,.]");
}

View File

@ -5,8 +5,8 @@ import org.bukkit.inventory.ItemStack;
public class MachineRecipe {
private int ticks;
private ItemStack[] input;
private ItemStack[] output;
private final ItemStack[] input;
private final ItemStack[] output;
public MachineRecipe(int seconds, ItemStack[] input, ItemStack[] output) {
this.ticks = seconds * 2;

View File

@ -25,7 +25,7 @@ public abstract class BlockMenuPreset extends ChestMenu {
// -1 means "automatically update according to the contents"
private int size = -1;
private boolean universal;
private final boolean universal;
private boolean locked;
private ItemManipulationEvent event;

View File

@ -143,8 +143,8 @@ public class DirtyChestMenu extends ChestMenu {
public static class SaveHandler implements MenuOpeningHandler {
private DirtyChestMenu menu;
private MenuOpeningHandler handler;
private final DirtyChestMenu menu;
private final MenuOpeningHandler handler;
public SaveHandler(DirtyChestMenu menu, MenuOpeningHandler handler) {
this.menu = menu;

View File

@ -237,4 +237,5 @@ slimefun:
auto_brewer: Industrial Brewery
enchantment_rune: Ancient Enchanting
lead_clothing: Lead Clothing
tape_measure: Tape Measure
tape_measure: Tape Measure
iron_golem_assembler: Automated Iron Golems

View File

@ -41,7 +41,7 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
public class TestBackpackListener {
private static int BACKPACK_SIZE = 27;
private static final int BACKPACK_SIZE = 27;
private static ServerMock server;
private static SlimefunPlugin plugin;
private static BackpackListener listener;