1
mirror of https://github.com/StarWishsama/Slimefun4.git synced 2024-09-20 03:35:51 +00:00

Merge pull request #1953 from TheBusyBiscuit/feature/miner

Added Industrial Miner & Removed Digital Miner
This commit is contained in:
TheBusyBiscuit 2020-06-09 23:23:56 +02:00 committed by GitHub
commit b659e51008
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
38 changed files with 826 additions and 274 deletions

View File

@ -24,11 +24,16 @@
* Added Dried Kelp Blocks recipe to the Electric Press
* Added Bone Blocks recipe to the Electric Press
* Added thai translations
* Added Industrial Miner
* Added Advanced Industrial Miner
* Added Cocoa Organic Food
* Added Cocoa Fertilizer
#### Changes
* Fixed a few memory leaks
* Removed Digital Miner
* Removed Advanced Digital Miner
* Dried Kelp Blocks can now be used in the Coal Generator
* Crafting Organic Food/Fertilizer yields more output now
* Organic Food (Melon) now uses Melon Slices instead of Melon blocks
@ -39,6 +44,7 @@
* Fixed Nuclear Reactors accepting Lava as coolant
## Release Candidate 12 (27 May 2020)
https://thebusybiscuit.github.io/builds/TheBusyBiscuit/Slimefun4/stable/#12
#### Additions
* Added Ukrainian translations
@ -83,6 +89,7 @@
* Fixed #1935
## Release Candidate 11 (25 Apr 2020)
https://thebusybiscuit.github.io/builds/TheBusyBiscuit/Slimefun4/stable/#11
#### Additions
* Added GEOResourceGenerationEvent

View File

@ -302,7 +302,7 @@
<dependency>
<groupId>com.github.thebusybiscuit</groupId>
<artifactId>CS-CoreLib2</artifactId>
<version>0.20.4</version>
<version>0.21</version>
<scope>compile</scope>
</dependency>
<dependency>

View File

@ -8,7 +8,7 @@ import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerEvent;
import io.github.thebusybiscuit.slimefun4.core.MultiBlock;
import io.github.thebusybiscuit.slimefun4.core.multiblocks.MultiBlock;
/**
* This {@link Event} is called when a {@link Player} interacts with a {@link MultiBlock}.

View File

@ -24,6 +24,7 @@ import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile;
import io.github.thebusybiscuit.slimefun4.core.attributes.WitherProof;
import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideImplementation;
import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideLayout;
import io.github.thebusybiscuit.slimefun4.core.multiblocks.MultiBlock;
import io.github.thebusybiscuit.slimefun4.core.researching.Research;
import io.github.thebusybiscuit.slimefun4.implementation.guide.BookSlimefunGuide;
import io.github.thebusybiscuit.slimefun4.implementation.guide.CheatSheetSlimefunGuide;

View File

@ -10,6 +10,7 @@ import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
import io.github.thebusybiscuit.cscorelib2.players.PlayerList;
import io.github.thebusybiscuit.slimefun4.core.commands.SlimefunCommand;
import io.github.thebusybiscuit.slimefun4.core.commands.SubCommand;
import io.github.thebusybiscuit.slimefun4.utils.PatternUtils;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.multiblocks.MultiBlockMachine;
@ -44,6 +45,7 @@ class GiveCommand extends SubCommand {
Player p = player.get();
SlimefunItem sfItem = SlimefunItem.getByID(args[2].toUpperCase(Locale.ROOT));
if (sfItem != null) {
if (sfItem instanceof MultiBlockMachine) {
SlimefunPlugin.getLocal().sendMessage(sender, "guide.cheat.no-multiblocks");
@ -74,7 +76,7 @@ class GiveCommand extends SubCommand {
int amount = 1;
if (args.length == 4) {
if (args[3].chars().allMatch(Character::isDigit)) {
if (PatternUtils.NUMERIC.matcher(args[3]).matches()) {
amount = Integer.parseInt(args[3]);
}
else {

View File

@ -1,4 +1,4 @@
package io.github.thebusybiscuit.slimefun4.core;
package io.github.thebusybiscuit.slimefun4.core.multiblocks;
import java.util.Arrays;
import java.util.HashSet;
@ -122,6 +122,16 @@ public class MultiBlock {
}
}
// This ensures that the Industrial Miner is still recognized while operating
if (a == Material.PISTON) {
return a == b || b == Material.MOVING_PISTON;
}
// This ensures that the Industrial Miner is still recognized while operating
if (b == Material.PISTON) {
return a == b || a == Material.MOVING_PISTON;
}
if (b != a) {
return false;
}

View File

@ -0,0 +1,5 @@
/**
* This package holds all core mechanics related to a
* {@link io.github.thebusybiscuit.slimefun4.core.multiblocks.MultiBlock}, like that class itself.
*/
package io.github.thebusybiscuit.slimefun4.core.multiblocks;

View File

@ -25,7 +25,6 @@ import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
import io.github.thebusybiscuit.cscorelib2.recipes.MinecraftRecipe;
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile;
import io.github.thebusybiscuit.slimefun4.core.MultiBlock;
import io.github.thebusybiscuit.slimefun4.core.attributes.RecipeDisplayItem;
import io.github.thebusybiscuit.slimefun4.core.categories.FlexCategory;
import io.github.thebusybiscuit.slimefun4.core.categories.LockedCategory;
@ -34,6 +33,7 @@ import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuide;
import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideImplementation;
import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideLayout;
import io.github.thebusybiscuit.slimefun4.core.guide.options.SlimefunGuideSettings;
import io.github.thebusybiscuit.slimefun4.core.multiblocks.MultiBlock;
import io.github.thebusybiscuit.slimefun4.core.researching.Research;
import io.github.thebusybiscuit.slimefun4.utils.ChatUtils;
import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils;

View File

@ -375,15 +375,15 @@ public abstract class ProgrammableAndroid extends Android implements InventoryBl
ItemStack item = menu.getItemInSlot(43);
if (item != null) {
for (MachineFuel recipe : recipes) {
if (SlimefunUtils.isItemSimilar(item, recipe.getInput(), true)) {
for (MachineFuel fuel : recipes) {
if (fuel.test(item)) {
menu.consumeItem(43);
if (getTier() == 2) {
menu.pushItem(new ItemStack(Material.BUCKET), getOutputSlots());
}
BlockStorage.addBlockInfo(b, "fuel", String.valueOf((int) (recipe.getTicks() * this.getFuelEfficiency())));
BlockStorage.addBlockInfo(b, "fuel", String.valueOf((int) (fuel.getTicks() * this.getFuelEfficiency())));
break;
}
}

View File

@ -1,12 +1,13 @@
package io.github.thebusybiscuit.slimefun4.implementation.items.food;
package io.github.thebusybiscuit.slimefun4.implementation.items.backpacks;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.slimefun4.implementation.items.backpacks.SlimefunBackpack;
import io.github.thebusybiscuit.slimefun4.implementation.items.food.Juice;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.CoolerListener;
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
/**
@ -26,4 +27,10 @@ public class Cooler extends SlimefunBackpack {
super(size, category, item, recipeType, recipe);
}
@Override
public boolean isItemAllowed(ItemStack item, SlimefunItem itemAsSlimefunItem) {
// A Cooler only allows Juices
return itemAsSlimefunItem instanceof Juice;
}
}

View File

@ -1,5 +1,6 @@
package io.github.thebusybiscuit.slimefun4.implementation.items.backpacks;
import org.bukkit.Material;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
@ -42,6 +43,27 @@ public class SlimefunBackpack extends SimpleSlimefunItem<ItemUseHandler> {
return size;
}
/**
* This method returns whether a given {@link ItemStack} is allowed to be stored
* in this {@link SlimefunBackpack}.
*
* @param item
* The {@link ItemStack} to check for
*
* @param itemAsSlimefunItem
* The same {@link ItemStack} as a {@link SlimefunItem}, might be null
*
* @return Whether the given {@link ItemStack} is allowed to be put into this {@link SlimefunBackpack}
*/
public boolean isItemAllowed(ItemStack item, SlimefunItem itemAsSlimefunItem) {
// Shulker Boxes are not allowed!
if (item.getType() == Material.SHULKER_BOX || item.getType().toString().endsWith("_SHULKER_BOX")) {
return false;
}
return !(itemAsSlimefunItem instanceof SlimefunBackpack);
}
@Override
public ItemUseHandler getItemHandler() {
return e -> {

View File

@ -20,6 +20,7 @@ public abstract class CoalGenerator extends AGenerator {
protected void registerDefaultFuelTypes() {
registerFuel(new MachineFuel(80, new ItemStack(Material.COAL_BLOCK)));
registerFuel(new MachineFuel(12, new ItemStack(Material.BLAZE_ROD)));
registerFuel(new MachineFuel(20, new ItemStack(Material.DRIED_KELP_BLOCK)));
// Coal & Charcoal
registerFuel(new MachineFuel(8, new ItemStack(Material.COAL)));

View File

@ -2,6 +2,7 @@ package io.github.thebusybiscuit.slimefun4.implementation.items.food;
import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.slimefun4.implementation.items.backpacks.Cooler;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.CoolerListener;
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category;

View File

@ -0,0 +1,363 @@
package io.github.thebusybiscuit.slimefun4.implementation.items.multiblocks.miner;
import java.util.UUID;
import java.util.logging.Level;
import org.bukkit.Bukkit;
import org.bukkit.Effect;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Particle;
import org.bukkit.Sound;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.Chest;
import org.bukkit.block.data.type.Piston;
import org.bukkit.block.data.type.PistonHead;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.cscorelib2.blocks.BlockPosition;
import io.github.thebusybiscuit.cscorelib2.inventory.InvUtils;
import io.github.thebusybiscuit.cscorelib2.inventory.ItemUtils;
import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction;
import io.github.thebusybiscuit.cscorelib2.scheduling.TaskQueue;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.MachineFuel;
import me.mrCookieSlime.Slimefun.api.Slimefun;
/**
* This represents a running instance of an {@link IndustrialMiner}.
*
* @author TheBusyBiscuit
*
* @see IndustrialMiner
* @see AdvancedIndustrialMiner
*
*/
class ActiveMiner implements Runnable {
private final IndustrialMiner miner;
private final UUID owner;
private int fuel = 0;
private int ores = 0;
private boolean running = false;
private final Block chest;
private final Block[] pistons;
private final BlockPosition start;
private final BlockPosition end;
private final int height;
private int x;
private int z;
public ActiveMiner(IndustrialMiner miner, UUID owner, Block chest, Block[] pistons, Block start, Block end) {
this.miner = miner;
this.owner = owner;
this.chest = chest;
this.pistons = pistons;
this.start = new BlockPosition(start);
this.end = new BlockPosition(end);
this.height = start.getY();
this.x = start.getX();
this.z = start.getZ();
}
/**
* This starts the {@link IndustrialMiner} at the given {@link Block}.
*
* @param b
* The {@link Block} which marks the center of this {@link IndustrialMiner}
*/
public void start(Block b) {
miner.activeMiners.put(b.getLocation(), this);
running = true;
warmUp();
}
/**
* This method stops the {@link IndustrialMiner}.
*/
public void stop() {
running = false;
miner.activeMiners.remove(chest.getRelative(BlockFace.DOWN).getLocation());
}
/**
* This method stops the {@link IndustrialMiner} with an error message.
* The error message is a path to the location in Slimefun's localization files.
*
* @param error
* The error message to send
*/
public void stop(String error) {
Player p = Bukkit.getPlayer(owner);
if (p != null) {
SlimefunPlugin.getLocal().sendMessage(p, error);
}
stop();
}
/**
* This method starts the warm-up animation for the {@link IndustrialMiner}.
*/
private void warmUp() {
fuel = consumeFuel();
if (fuel <= 0) {
// This Miner has not enough fuel.
stop("machines.INDUSTRIAL_MINER.no-fuel");
return;
}
// This is our warm up animation
// The pistons will push after another in decreasing intervals
TaskQueue queue = new TaskQueue();
queue.thenRun(4, () -> setPistonState(pistons[0], true));
queue.thenRun(10, () -> setPistonState(pistons[0], false));
queue.thenRun(8, () -> setPistonState(pistons[1], true));
queue.thenRun(10, () -> setPistonState(pistons[1], false));
queue.thenRun(6, () -> setPistonState(pistons[0], true));
queue.thenRun(9, () -> setPistonState(pistons[0], false));
queue.thenRun(4, () -> setPistonState(pistons[1], true));
queue.thenRun(7, () -> setPistonState(pistons[1], false));
queue.thenRun(3, () -> setPistonState(pistons[0], true));
queue.thenRun(5, () -> setPistonState(pistons[0], false));
queue.thenRun(2, () -> setPistonState(pistons[1], true));
queue.thenRun(4, () -> setPistonState(pistons[1], false));
queue.thenRun(1, () -> setPistonState(pistons[0], true));
queue.thenRun(3, () -> setPistonState(pistons[0], false));
queue.thenRun(1, () -> setPistonState(pistons[1], true));
queue.thenRun(2, () -> setPistonState(pistons[1], false));
queue.thenRun(1, this);
queue.execute(SlimefunPlugin.instance);
}
@Override
public void run() {
if (!running) {
// Don't continue if the machine has stopped
return;
}
TaskQueue queue = new TaskQueue();
queue.thenRun(1, () -> setPistonState(pistons[0], true));
queue.thenRun(3, () -> setPistonState(pistons[0], false));
queue.thenRun(1, () -> setPistonState(pistons[1], true));
queue.thenRun(3, () -> setPistonState(pistons[1], false));
queue.thenRun(() -> {
try {
Block furnace = chest.getRelative(BlockFace.DOWN);
furnace.getWorld().playEffect(furnace.getLocation(), Effect.STEP_SOUND, Material.STONE);
for (int y = height; y > 0; y--) {
Block b = start.getWorld().getBlockAt(x, y, z);
if (!SlimefunPlugin.getProtectionManager().hasPermission(Bukkit.getOfflinePlayer(owner), b, ProtectableAction.BREAK_BLOCK)) {
stop("machines.INDUSTRIAL_MINER.no-permission");
return;
}
if (miner.canMine(b.getType()) && push(miner.getOutcome(b.getType()))) {
furnace.getWorld().playEffect(furnace.getLocation(), Effect.STEP_SOUND, b.getType());
furnace.getWorld().playSound(furnace.getLocation(), Sound.ENTITY_ARROW_HIT_PLAYER, 0.2F, 1F);
b.setType(Material.AIR);
fuel--;
ores++;
// Repeat the same column when we hit an ore.
Slimefun.runSync(this, 4);
return;
}
}
nextColumn();
}
catch (Exception e) {
Slimefun.getLogger().log(Level.SEVERE, e, () -> "An Error occured while running an Industrial Miner at " + new BlockPosition(chest));
stop();
}
});
queue.execute(SlimefunPlugin.instance);
}
/**
* This advanced the {@link IndustrialMiner} to the next column
*/
private void nextColumn() {
if (x < end.getX()) {
x++;
}
else if (z < end.getZ()) {
x = start.getX();
z++;
}
else {
// The Miner has finished
stop();
Player p = Bukkit.getPlayer(owner);
if (p != null) {
p.playSound(p.getLocation(), Sound.ENTITY_ARROW_HIT_PLAYER, 0.4F, 1F);
SlimefunPlugin.getLocal().sendMessage(p, "machines.INDUSTRIAL_MINER.finished", msg -> msg.replace("%ores%", String.valueOf(ores)));
}
return;
}
Slimefun.runSync(this, 5);
}
/**
* This refuels the {@link IndustrialMiner} and pushes the given {@link ItemStack} to
* its {@link Chest}.
*
* @param item
* The {@link ItemStack} to push to the {@link Chest}.
*
* @return Whether the operation was successful
*/
private boolean push(ItemStack item) {
if (fuel < 1) {
// Restock fuel
fuel = consumeFuel();
}
// Check if there is enough fuel to run
if (fuel > 0) {
if (chest.getType() == Material.CHEST) {
Inventory inv = ((Chest) chest.getState()).getBlockInventory();
if (InvUtils.fits(inv, item)) {
inv.addItem(item);
return true;
}
else {
stop("machines.INDUSTRIAL_MINER.chest-full");
}
}
else {
// The chest has been destroyed
stop("machines.INDUSTRIAL_MINER.destroyed");
}
}
else {
stop("machines.INDUSTRIAL_MINER.no-fuel");
}
return false;
}
/**
* This consumes fuel from the given {@link Chest}.
*
* @return The gained fuel value
*/
private int consumeFuel() {
if (chest.getType() == Material.CHEST) {
Inventory inv = ((Chest) chest.getState()).getBlockInventory();
for (int i = 0; i < inv.getSize(); i++) {
for (MachineFuel fuelType : miner.fuelTypes) {
ItemStack item = inv.getContents()[i];
if (fuelType.test(item)) {
ItemUtils.consumeItem(item, false);
if (miner instanceof AdvancedIndustrialMiner) {
inv.addItem(new ItemStack(Material.BUCKET));
}
return fuelType.getTicks();
}
}
}
}
return 0;
}
private void setPistonState(Block block, boolean extended) {
if (!running) {
return;
}
try {
// Smoke Particles around the Chest for dramatic effect
Location particleLoc = chest.getLocation().clone().add(0, -1, 0);
block.getWorld().spawnParticle(Particle.SMOKE_NORMAL, particleLoc, 20, 0.7, 0.7, 0.7, 0);
if (block.getType() == Material.MOVING_PISTON) {
// Yeah it isn't really cool when this happens
block.getRelative(BlockFace.UP).setType(Material.AIR);
}
else if (block.getType() == Material.PISTON) {
Block above = block.getRelative(BlockFace.UP);
if (above.isEmpty() || above.getType() == Material.PISTON_HEAD) {
Piston piston = (Piston) block.getBlockData();
if (piston.getFacing() == BlockFace.UP) {
piston.setExtended(extended);
block.setBlockData(piston, false);
// Updating the Piston Head
if (extended) {
PistonHead head = (PistonHead) Material.PISTON_HEAD.createBlockData();
head.setFacing(BlockFace.UP);
block.getRelative(BlockFace.UP).setBlockData(head, false);
}
else {
block.getRelative(BlockFace.UP).setType(Material.AIR);
}
block.getWorld().playSound(block.getLocation(), extended ? Sound.BLOCK_PISTON_EXTEND : Sound.BLOCK_PISTON_CONTRACT, 0.1F, 1F);
}
else {
// The pistons must be facing upwards
stop("machines.INDUSTRIAL_MINER.piston-facing");
}
}
else {
// The pistons must be facing upwards
stop("machines.INDUSTRIAL_MINER.piston-space");
}
}
else {
// The piston has been destroyed
stop("machines.INDUSTRIAL_MINER.destroyed");
}
}
catch (Exception e) {
Slimefun.getLogger().log(Level.SEVERE, e, () -> "An Error occured while moving a Piston for an Industrial Miner at " + new BlockPosition(block));
stop();
}
}
}

View File

@ -0,0 +1,34 @@
package io.github.thebusybiscuit.slimefun4.implementation.items.multiblocks.miner;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import me.mrCookieSlime.Slimefun.Lists.SlimefunItems;
import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.MachineFuel;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
/**
* The {@link AdvancedIndustrialMiner} is a more advanced version of the {@link IndustrialMiner}.
* It uses Silk Touch and has a bigger range.
*
* @author TheBusyBiscuit
*
* @see IndustrialMiner
* @see ActiveMiner
*
*/
public class AdvancedIndustrialMiner extends IndustrialMiner {
public AdvancedIndustrialMiner(Category category, SlimefunItemStack item) {
super(category, item, Material.DIAMOND_BLOCK, true, 5);
}
@Override
protected void registerDefaultFuelTypes() {
fuelTypes.add(new MachineFuel(48, new ItemStack(Material.LAVA_BUCKET)));
fuelTypes.add(new MachineFuel(64, SlimefunItems.BUCKET_OF_OIL));
fuelTypes.add(new MachineFuel(128, SlimefunItems.BUCKET_OF_FUEL));
}
}

View File

@ -0,0 +1,213 @@
package io.github.thebusybiscuit.slimefun4.implementation.items.multiblocks.miner;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;
import org.apache.commons.lang.Validate;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Tag;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import io.github.thebusybiscuit.cscorelib2.chat.ChatColors;
import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.MachineFuel;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.multiblocks.MultiBlockMachine;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
/**
* The {@link IndustrialMiner} is a {@link MultiBlockMachine} that can mine any
* ores it finds in a given range underneath where it was placed.
*
* <i>And for those of you who are wondering... yes this is the replacement for the
* long-time deprecated Digital Miner.</i>
*
* @author TheBusyBiscuit
*
* @see AdvancedIndustrialMiner
* @see ActiveMiner
*
*/
public class IndustrialMiner extends MultiBlockMachine {
protected final Map<Location, ActiveMiner> activeMiners = new HashMap<>();
protected final List<MachineFuel> fuelTypes = new ArrayList<>();
private final int range;
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);
this.range = range;
this.silkTouch = silkTouch;
registerDefaultFuelTypes();
}
/**
* This returns whether this {@link IndustrialMiner} will output ores as they are.
* Similar to the Silk Touch {@link Enchantment}.
*
* @return Whether to treat ores with Silk Touch
*/
public boolean hasSilkTouch() {
return silkTouch;
}
/**
* This method returns the range of the {@link IndustrialMiner}.
* The total area will be determined by the range multiplied by 2 plus the actual center
* of the machine.
*
* So a range of 3 will make the {@link IndustrialMiner} affect an area of 7x7 blocks.
* 3 on all axis, plus the center of the machine itself.
*
* @return The range of this {@link IndustrialMiner}
*/
public int getRange() {
return range;
}
/**
* This registers the various types of fuel that can be used in the
* {@link IndustrialMiner}.
*/
protected void registerDefaultFuelTypes() {
// Coal & Charcoal
fuelTypes.add(new MachineFuel(4, new ItemStack(Material.COAL)));
fuelTypes.add(new MachineFuel(4, new ItemStack(Material.CHARCOAL)));
fuelTypes.add(new MachineFuel(40, new ItemStack(Material.COAL_BLOCK)));
fuelTypes.add(new MachineFuel(10, new ItemStack(Material.DRIED_KELP_BLOCK)));
fuelTypes.add(new MachineFuel(4, new ItemStack(Material.BLAZE_ROD)));
// Logs
for (Material mat : Tag.LOGS.getValues()) {
fuelTypes.add(new MachineFuel(1, new ItemStack(mat)));
}
}
/**
* This method returns the outcome that mining certain ores yields.
*
* @param ore
* The {@link Material} of the ore that was mined
*
* @return The outcome when mining this ore
*/
public ItemStack getOutcome(Material ore) {
if (hasSilkTouch()) {
return new ItemStack(ore);
}
Random random = ThreadLocalRandom.current();
switch (ore) {
case COAL_ORE:
return new ItemStack(Material.COAL);
case DIAMOND_ORE:
return new ItemStack(Material.DIAMOND);
case EMERALD_ORE:
return new ItemStack(Material.EMERALD);
case NETHER_QUARTZ_ORE:
return new ItemStack(Material.QUARTZ);
case REDSTONE_ORE:
return new ItemStack(Material.REDSTONE, 4 + random.nextInt(2));
case LAPIS_ORE:
return new ItemStack(Material.LAPIS_LAZULI, 4 + random.nextInt(4));
default:
// This includes Iron and Gold ore
return new ItemStack(ore);
}
}
/**
* This registers a new fuel type for this {@link IndustrialMiner}.
*
* @param ores
* The amount of ores this allows you to mine
* @param item
* The item that shall be consumed
*/
public void addFuelType(int ores, ItemStack item) {
Validate.isTrue(ores > 1 && ores % 2 == 0, "The amount of ores must be at least 2 and a multiple of 2.");
fuelTypes.add(new MachineFuel(ores / 2, item));
}
@Override
public String getLabelLocalPath() {
return "guide.tooltips.recipes.generator";
}
@Override
public List<ItemStack> getDisplayRecipes() {
List<ItemStack> list = new ArrayList<>();
for (MachineFuel fuel : fuelTypes) {
ItemStack item = fuel.getInput().clone();
ItemMeta im = item.getItemMeta();
List<String> lore = new ArrayList<>();
lore.add(ChatColors.color("&8\u21E8 &7Lasts for max. " + fuel.getTicks() + " Ores"));
im.setLore(lore);
item.setItemMeta(im);
list.add(item);
}
return list;
}
@Override
public void onInteract(Player p, Block b) {
if (activeMiners.containsKey(b.getLocation())) {
SlimefunPlugin.getLocal().sendMessage(p, "machines.INDUSTRIAL_MINER.already-running");
return;
}
Block chest = b.getRelative(BlockFace.UP);
Block[] pistons = findPistons(chest);
int mod = getRange();
Block start = b.getRelative(-mod, -1, -mod);
Block end = b.getRelative(mod, -1, mod);
ActiveMiner instance = new ActiveMiner(this, p.getUniqueId(), chest, pistons, start, end);
instance.start(b);
}
private Block[] findPistons(Block chest) {
Block northern = chest.getRelative(BlockFace.NORTH);
if (northern.getType() == Material.PISTON) {
return new Block[] { northern, chest.getRelative(BlockFace.SOUTH) };
}
else {
return new Block[] { chest.getRelative(BlockFace.WEST), chest.getRelative(BlockFace.EAST) };
}
}
/**
* This returns whether this {@link IndustrialMiner} can mine the given {@link Material}.
*
* @param type
* The {@link Material} to check
*
* @return Whether this {@link IndustrialMiner} is capable of mining this {@link Material}
*/
public boolean canMine(Material type) {
return type.name().endsWith("_ORE");
}
}

View File

@ -0,0 +1,5 @@
/**
* This package holds classes associated with the
* {@link io.github.thebusybiscuit.slimefun4.implementation.items.multiblocks.IndustrialMiner}.
*/
package io.github.thebusybiscuit.slimefun4.implementation.items.multiblocks.miner;

View File

@ -23,9 +23,8 @@ import org.bukkit.inventory.meta.ItemMeta;
import io.github.thebusybiscuit.slimefun4.api.player.PlayerBackpack;
import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile;
import io.github.thebusybiscuit.slimefun4.implementation.items.backpacks.Cooler;
import io.github.thebusybiscuit.slimefun4.implementation.items.backpacks.SlimefunBackpack;
import io.github.thebusybiscuit.slimefun4.implementation.items.food.Cooler;
import io.github.thebusybiscuit.slimefun4.implementation.items.food.Juice;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.api.Slimefun;
@ -83,21 +82,31 @@ public class BackpackListener implements Listener {
if (item != null) {
SlimefunItem backpack = SlimefunItem.getByItem(item);
if (e.getClick() == ClickType.NUMBER_KEY) {
if (e.getClickedInventory().getType() != InventoryType.PLAYER) {
ItemStack hotbarItem = e.getWhoClicked().getInventory().getItem(e.getHotbarButton());
if (backpack instanceof SlimefunBackpack) {
if (e.getClick() == ClickType.NUMBER_KEY) {
if (e.getClickedInventory().getType() != InventoryType.PLAYER) {
ItemStack hotbarItem = e.getWhoClicked().getInventory().getItem(e.getHotbarButton());
if (!isItemAllowed(hotbarItem, backpack)) {
e.setCancelled(true);
if (!isAllowed((SlimefunBackpack) backpack, hotbarItem)) {
e.setCancelled(true);
}
}
}
}
else if (!isItemAllowed(e.getCurrentItem(), backpack)) {
e.setCancelled(true);
else if (!isAllowed((SlimefunBackpack) backpack, e.getCurrentItem())) {
e.setCancelled(true);
}
}
}
}
private boolean isAllowed(SlimefunBackpack backpack, ItemStack item) {
if (item == null || item.getType() == Material.AIR) {
return true;
}
return backpack.isItemAllowed(item, SlimefunItem.getByItem(item));
}
public void openBackpack(Player p, ItemStack item, SlimefunBackpack backpack) {
if (item.getAmount() == 1) {
if (Slimefun.hasUnlocked(p, backpack, true) && !PlayerProfile.get(p, profile -> openBackpack(p, item, profile, backpack.getSize()))) {
@ -109,28 +118,6 @@ public class BackpackListener implements Listener {
}
}
private boolean isItemAllowed(ItemStack item, SlimefunItem backpack) {
if (item == null || item.getType() == Material.AIR) {
return true;
}
if (item.getType() == Material.SHULKER_BOX || item.getType().toString().endsWith("_SHULKER_BOX")) {
return false;
}
SlimefunItem slimefunItem = SlimefunItem.getByItem(item);
if (slimefunItem instanceof SlimefunBackpack) {
return false;
}
if (backpack instanceof Cooler) {
return slimefunItem instanceof Juice;
}
return true;
}
private void openBackpack(Player p, ItemStack item, PlayerProfile profile, int size) {
List<String> lore = item.getItemMeta().getLore();
for (int line = 0; line < lore.size(); line++) {

View File

@ -13,7 +13,7 @@ import org.bukkit.potion.PotionEffect;
import io.github.thebusybiscuit.slimefun4.api.player.PlayerBackpack;
import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile;
import io.github.thebusybiscuit.slimefun4.implementation.items.food.Cooler;
import io.github.thebusybiscuit.slimefun4.implementation.items.backpacks.Cooler;
import io.github.thebusybiscuit.slimefun4.implementation.items.food.Juice;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.api.Slimefun;

View File

@ -15,7 +15,7 @@ import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.EquipmentSlot;
import io.github.thebusybiscuit.slimefun4.api.events.MultiBlockInteractEvent;
import io.github.thebusybiscuit.slimefun4.core.MultiBlock;
import io.github.thebusybiscuit.slimefun4.core.multiblocks.MultiBlock;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.Objects.handlers.MultiBlockInteractionHandler;

View File

@ -0,0 +1,6 @@
/**
* This package holds all classes that are related to the actual implementation of this plugin.
* This includes implementations of {@link me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem} but also any
* {@link org.bukkit.event.Listener}.
*/
package io.github.thebusybiscuit.slimefun4.implementation;

View File

@ -117,10 +117,8 @@ public final class ResearchSetup {
register("table_saw", 92, "Table Saw", 4, SlimefunItems.TABLE_SAW);
register("slime_steel_armor", 93, "Slimy Steel Armor", 27, SlimefunItems.SLIME_HELMET_STEEL, SlimefunItems.SLIME_CHESTPLATE_STEEL, SlimefunItems.SLIME_LEGGINGS_STEEL, SlimefunItems.SLIME_BOOTS_STEEL);
register("blade_of_vampires", 94, "Blade of Vampires", 26, SlimefunItems.BLADE_OF_VAMPIRES);
register("digital_miner", 95, "Lazy Mining", 40, SlimefunItems.DIGITAL_MINER);
register("water_staff", 96, "Water Staff", 8, SlimefunItems.STAFF_WATER);
register("24k_gold_block", 97, "Golden City", 19, SlimefunItems.GOLD_24K_BLOCK);
register("advanced_digital_miner", 98, "Advanced Mining 101", 42, SlimefunItems.ADVANCED_DIGITAL_MINER);
register("composter", 99, "Composting Dirt", 3, SlimefunItems.COMPOSTER);
register("farmer_shoes", 100, "Farmer Shoes", 4, SlimefunItems.FARMER_SHOES);
register("explosive_tools", 101, "Explosive Tools", 30, SlimefunItems.EXPLOSIVE_PICKAXE, SlimefunItems.EXPLOSIVE_SHOVEL);
@ -265,6 +263,8 @@ public final class ResearchSetup {
register("kelp_cookie", 254, "Tasty Kelp", 4, SlimefunItems.KELP_COOKIE);
register("makeshift_smeltery", 255, "Improvised Smeltery", 6, SlimefunItems.MAKESHIFT_SMELTERY);
register("tree_growth_accelerator", 256, "Faster Trees", 18, SlimefunItems.TREE_GROWTH_ACCELERATOR);
register("industrial_miner", 95, "Industrial Mining", 28, SlimefunItems.INDUSTRIAL_MINER);
register("advanced_industrial_miner", 98, "Better Mining", 36, SlimefunItems.ADVANCED_INDUSTRIAL_MINER);
}
private static void register(String key, int id, String name, int defaultCost, ItemStack... items) {

View File

@ -3,28 +3,16 @@ package io.github.thebusybiscuit.slimefun4.implementation.setup;
import java.util.ArrayList;
import java.util.List;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Effect;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.Sound;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.Chest;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import io.github.thebusybiscuit.cscorelib2.inventory.InvUtils;
import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
import io.github.thebusybiscuit.cscorelib2.materials.MaterialCollections;
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
import io.github.thebusybiscuit.slimefun4.api.SlimefunAddon;
import io.github.thebusybiscuit.slimefun4.core.MultiBlock;
import io.github.thebusybiscuit.slimefun4.core.attributes.Radioactivity;
import io.github.thebusybiscuit.slimefun4.implementation.items.RadioactiveItem;
import io.github.thebusybiscuit.slimefun4.implementation.items.VanillaItem;
@ -40,6 +28,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.items.androids.Programm
import io.github.thebusybiscuit.slimefun4.implementation.items.androids.WoodcutterAndroid;
import io.github.thebusybiscuit.slimefun4.implementation.items.armor.Parachute;
import io.github.thebusybiscuit.slimefun4.implementation.items.armor.SlimefunArmorPiece;
import io.github.thebusybiscuit.slimefun4.implementation.items.backpacks.Cooler;
import io.github.thebusybiscuit.slimefun4.implementation.items.backpacks.EnderBackpack;
import io.github.thebusybiscuit.slimefun4.implementation.items.backpacks.RestoredBackpack;
import io.github.thebusybiscuit.slimefun4.implementation.items.backpacks.SlimefunBackpack;
@ -107,7 +96,6 @@ import io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines
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.food.BirthdayCake;
import io.github.thebusybiscuit.slimefun4.implementation.items.food.Cooler;
import io.github.thebusybiscuit.slimefun4.implementation.items.food.DietCookie;
import io.github.thebusybiscuit.slimefun4.implementation.items.food.FortuneCookie;
import io.github.thebusybiscuit.slimefun4.implementation.items.food.Juice;
@ -157,6 +145,8 @@ import io.github.thebusybiscuit.slimefun4.implementation.items.multiblocks.OreWa
import io.github.thebusybiscuit.slimefun4.implementation.items.multiblocks.PressureChamber;
import io.github.thebusybiscuit.slimefun4.implementation.items.multiblocks.Smeltery;
import io.github.thebusybiscuit.slimefun4.implementation.items.multiblocks.TableSaw;
import io.github.thebusybiscuit.slimefun4.implementation.items.multiblocks.miner.AdvancedIndustrialMiner;
import io.github.thebusybiscuit.slimefun4.implementation.items.multiblocks.miner.IndustrialMiner;
import io.github.thebusybiscuit.slimefun4.implementation.items.seasonal.ChristmasPresent;
import io.github.thebusybiscuit.slimefun4.implementation.items.seasonal.EasterEgg;
import io.github.thebusybiscuit.slimefun4.implementation.items.tools.ExplosivePickaxe;
@ -178,17 +168,12 @@ import io.github.thebusybiscuit.slimefun4.implementation.items.weapons.SeismicAx
import io.github.thebusybiscuit.slimefun4.implementation.items.weapons.SwordOfBeheading;
import io.github.thebusybiscuit.slimefun4.implementation.items.weapons.VampireBlade;
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
import me.mrCookieSlime.CSCoreLibPlugin.CSCoreLib;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Lists.SlimefunItems;
import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunMachine;
import me.mrCookieSlime.Slimefun.Objects.handlers.MultiBlockInteractionHandler;
import me.mrCookieSlime.Slimefun.Objects.handlers.RainbowTicker;
import me.mrCookieSlime.Slimefun.api.BlockStorage;
import me.mrCookieSlime.Slimefun.api.Slimefun;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
/**
@ -1019,142 +1004,6 @@ public final class SlimefunItemSetup {
new ItemStack[] {null, new ItemStack(Material.WITHER_SKELETON_SKULL), null, null, new ItemStack(Material.WITHER_SKELETON_SKULL), null, null, new ItemStack(Material.BLAZE_ROD), null})
.register(plugin);
SlimefunMachine miner = new SlimefunMachine(categories.basicMachines, SlimefunItems.DIGITAL_MINER, "DIGITAL_MINER",
new ItemStack[] {SlimefunItems.SOLAR_PANEL, new ItemStack(Material.CHEST), SlimefunItems.SOLAR_PANEL, new ItemStack(Material.IRON_BLOCK), new ItemStack(Material.DISPENSER), new ItemStack(Material.IRON_BLOCK), new ItemStack(Material.IRON_BLOCK), new ItemStack(Material.HOPPER), new ItemStack(Material.IRON_BLOCK)},
BlockFace.SELF);
miner.addItemHandler(new MultiBlockInteractionHandler() {
@Override
public boolean onInteract(Player p, MultiBlock mb, Block b) {
if (mb.equals(((SlimefunMachine) SlimefunItem.getByID("DIGITAL_MINER")).getMultiBlock())) {
p.sendMessage(ChatColor.DARK_RED + "THIS MACHINE WILL SOON BE REMOVED!");
if (CSCoreLib.getLib().getProtectionManager().canAccessChest(p.getUniqueId(), b, true) && Slimefun.hasUnlocked(p, SlimefunItems.DIGITAL_MINER, true)) {
Block chestBlock = b.getRelative(BlockFace.UP);
if(!(BlockStorage.check(chestBlock.getRelative(BlockFace.WEST), "SOLAR_PANEL") && BlockStorage.check(chestBlock.getRelative(BlockFace.EAST), "SOLAR_PANEL")) &&
!(BlockStorage.check(chestBlock.getRelative(BlockFace.NORTH), "SOLAR_PANEL") && BlockStorage.check(chestBlock.getRelative(BlockFace.SOUTH), "SOLAR_PANEL"))) {
return false;
}
Chest chest = (Chest) chestBlock.getState();
Inventory inv = chest.getInventory();
List<Location> ores = new ArrayList<>();
for (int x = b.getX() - 4; x <= b.getX() + 4; x++) {
for (int z = b.getZ() - 4; z <= b.getZ() + 4; z++) {
for (int y = b.getY(); y > 0; y--) {
if (b.getWorld().getBlockAt(x, y, z).getType().toString().endsWith("_ORE")) {
ores.add(b.getWorld().getBlockAt(x, y, z).getLocation());
}
}
}
}
if (!ores.isEmpty()) {
Material ore = ores.get(0).getBlock().getType();
ItemStack adding = new ItemStack(ore);
ores.get(0).getBlock().setType(Material.AIR);
ores.clear();
if (InvUtils.fits(inv, adding)) {
for (int i = 0; i < 4; i++) {
int j = i;
Bukkit.getScheduler().runTaskLater(SlimefunPlugin.instance, () -> {
if (j < 3) {
b.getWorld().playEffect(b.getLocation(), Effect.STEP_SOUND, ore);
}
else {
p.getWorld().playSound(p.getLocation(), Sound.ENTITY_ARROW_HIT_PLAYER, 1F, 1F);
inv.addItem(adding);
}
}, i*20L);
}
}
else SlimefunPlugin.getLocal().sendMessage(p, "machines.full-inventory", true);
}
else SlimefunPlugin.getLocal().sendMessage(p, "miner.no-ores", true);
}
return true;
}
else return false;
}
});
miner.register(plugin);
SlimefunMachine advancedMiner = new SlimefunMachine(categories.basicMachines, SlimefunItems.ADVANCED_DIGITAL_MINER, "ADVANCED_DIGITAL_MINER",
new ItemStack[] {SlimefunItems.SOLAR_PANEL, new ItemStack(Material.CHEST), SlimefunItems.SOLAR_PANEL, SlimefunItems.GOLD_24K_BLOCK, new ItemStack(Material.DISPENSER), SlimefunItems.GOLD_24K_BLOCK, SlimefunItems.GOLD_24K_BLOCK, new ItemStack(Material.HOPPER), SlimefunItems.GOLD_24K_BLOCK},
BlockFace.SELF);
advancedMiner.addItemHandler(new MultiBlockInteractionHandler() {
// Determines the drops an Advanced Digital Miner will get
private final ItemStack effectivePickaxe = new ItemStack(Material.DIAMOND_PICKAXE);
@Override
public boolean onInteract(Player p, MultiBlock mb, Block b) {
if (mb.equals(((SlimefunMachine) SlimefunItem.getByID("ADVANCED_DIGITAL_MINER")).getMultiBlock())) {
p.sendMessage(ChatColor.DARK_RED + "THIS MACHINE WILL SOON BE REMOVED!");
if (CSCoreLib.getLib().getProtectionManager().canAccessChest(p.getUniqueId(), b, true) && Slimefun.hasUnlocked(p, SlimefunItems.ADVANCED_DIGITAL_MINER, true)) {
Block chestBlock = b.getRelative(BlockFace.UP);
if(!(BlockStorage.check(chestBlock.getRelative(BlockFace.WEST), "SOLAR_PANEL") && BlockStorage.check(chestBlock.getRelative(BlockFace.EAST), "SOLAR_PANEL")) &&
!(BlockStorage.check(chestBlock.getRelative(BlockFace.NORTH), "SOLAR_PANEL") && BlockStorage.check(chestBlock.getRelative(BlockFace.SOUTH), "SOLAR_PANEL"))) {
return false;
}
Chest chest = (Chest) chestBlock.getState();
Inventory inv = chest.getInventory();
List<Location> ores = new ArrayList<>();
for (int x = b.getX() - 6; x <= b.getX() + 6; x++) {
for (int z = b.getZ() - 6; z <= b.getZ() + 6; z++) {
for (int y = b.getY(); y > 0; y--) {
if (b.getWorld().getBlockAt(x, y, z).getType().toString().endsWith("_ORE")) {
ores.add(b.getWorld().getBlockAt(x, y, z).getLocation());
}
}
}
}
if (!ores.isEmpty()) {
Material ore = ores.get(0).getBlock().getType();
ItemStack drop = new ItemStack(ore);
if (ore == Material.COAL_ORE) drop = new ItemStack(Material.COAL, 4);
else if (ore == Material.IRON_ORE) drop = new CustomItem(SlimefunItems.IRON_DUST, 2);
else if (ore == Material.GOLD_ORE) drop = new CustomItem(SlimefunItems.GOLD_DUST, 2);
else if (ore == Material.REDSTONE_ORE) drop = new ItemStack(Material.REDSTONE, 8);
else if (ore == Material.NETHER_QUARTZ_ORE) drop = new ItemStack(Material.QUARTZ, 4);
else if (ore == Material.LAPIS_ORE) drop = new ItemStack(Material.LAPIS_LAZULI, 12);
else {
for (ItemStack drops : ores.get(0).getBlock().getDrops(effectivePickaxe)) {
if (!drops.getType().isBlock()) drop = new CustomItem(drops, 2);
}
}
final ItemStack adding = drop;
ores.get(0).getBlock().setType(Material.AIR);
ores.clear();
if (InvUtils.fits(inv, adding)) {
for (int i = 0; i < 4; i++) {
int j = i;
Bukkit.getScheduler().runTaskLater(SlimefunPlugin.instance, () -> {
if (j < 3) {
b.getWorld().playEffect(b.getLocation(), Effect.STEP_SOUND, ore);
}
else {
p.getWorld().playSound(p.getLocation(), Sound.ENTITY_ARROW_HIT_PLAYER, 1F, 1F);
inv.addItem(adding);
}
}, i*20L);
}
}
else SlimefunPlugin.getLocal().sendMessage(p, "machines.full-inventory", true);
}
else SlimefunPlugin.getLocal().sendMessage(p, "miner.no-ores", true);
}
return true;
}
else return false;
}
});
advancedMiner.register(plugin);
new SlimefunItem(categories.misc, (SlimefunItemStack) SlimefunItems.GOLD_24K_BLOCK, RecipeType.ENHANCED_CRAFTING_TABLE,
new ItemStack[] {SlimefunItems.GOLD_24K, SlimefunItems.GOLD_24K, SlimefunItems.GOLD_24K, SlimefunItems.GOLD_24K, SlimefunItems.GOLD_24K, SlimefunItems.GOLD_24K, SlimefunItems.GOLD_24K, SlimefunItems.GOLD_24K, SlimefunItems.GOLD_24K})
.register(plugin);
@ -1176,6 +1025,9 @@ public final class SlimefunItemSetup {
.register(plugin);
new AutomatedPanningMachine(categories.basicMachines).register(plugin);
new IndustrialMiner(categories.basicMachines, SlimefunItems.INDUSTRIAL_MINER, Material.IRON_BLOCK, false, 3).register(plugin);
new AdvancedIndustrialMiner(categories.basicMachines, SlimefunItems.ADVANCED_INDUSTRIAL_MINER).register(plugin);
new SlimefunItem(categories.magicalArmor, SlimefunItems.BOOTS_OF_THE_STOMPER, RecipeType.ARMOR_FORGE,
new ItemStack[] {null, null, null, new ItemStack(Material.YELLOW_WOOL), null, new ItemStack(Material.YELLOW_WOOL), new ItemStack(Material.PISTON), null, new ItemStack(Material.PISTON)})

View File

@ -6,12 +6,12 @@ import java.util.Map;
import org.bukkit.Color;
import org.bukkit.Material;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
import io.github.thebusybiscuit.slimefun4.core.attributes.MachineTier;
import io.github.thebusybiscuit.slimefun4.core.attributes.MachineType;
@ -514,34 +514,41 @@ public final class SlimefunItems {
STAFF_STORM.addUnsafeEnchantment(Enchantment.DURABILITY, 1);
}
/* Machines */
/* Multiblocks */
public static final SlimefunItemStack ENHANCED_CRAFTING_TABLE = new SlimefunItemStack("ENHANCED_CRAFTING_TABLE", Material.CRAFTING_TABLE, "&eEnhanced Crafting Table", "", "&aA regular Crafting Table cannot", "&ahold this massive Amount of Power...");
public static final SlimefunItemStack GRIND_STONE = new SlimefunItemStack("GRIND_STONE", Material.DISPENSER, "&bGrind Stone", "", "&aGrinds items down into other items");
public static final SlimefunItemStack ARMOR_FORGE = new SlimefunItemStack("ARMOR_FORGE", Material.ANVIL, "&6Armor Forge", "", "&aGives you the ability to create powerful armor");
public static final SlimefunItemStack MAKESHIFT_SMELTERY;
public static final SlimefunItemStack SMELTERY = new SlimefunItemStack("SMELTERY", Material.FURNACE, "&6Smeltery", "", "&rA high-temperature furnace", "&rthat allows you to smelt dusts", "&rinto ingots and create alloys.");
public static final SlimefunItemStack IGNITION_CHAMBER = new SlimefunItemStack("IGNITION_CHAMBER", Material.DROPPER, "&4Automatic Ignition Chamber", "", "&rPrevents the Smeltery from using up fire.", "&rJust fill it up with \"Flint and Steel\"", "&rand place it adjacent to the Smeltery's dispenser");
public static final SlimefunItemStack ORE_CRUSHER = new SlimefunItemStack("ORE_CRUSHER", Material.DISPENSER, "&bOre Crusher", "", "&aCrushes ores to double them");
public static final SlimefunItemStack COMPRESSOR = new SlimefunItemStack("COMPRESSOR", Material.PISTON, "&bCompressor", "", "&aCompresses Items");
public static final SlimefunItemStack PRESSURE_CHAMBER = new SlimefunItemStack("PRESSURE_CHAMBER", Material.GLASS, "&bPressure Chamber", "", "&aCompresses Items even further");
public static final SlimefunItemStack MAGIC_WORKBENCH = new SlimefunItemStack("MAGIC_WORKBENCH", Material.CRAFTING_TABLE, "&6Magic Workbench", "", "&dInfuses Items with magical Energy");
public static final SlimefunItemStack ORE_WASHER = new SlimefunItemStack("ORE_WASHER", Material.CAULDRON, "&6Ore Washer", "", "&aWashes Sifted Ore to filter Ores", "&aand gives you small Stone Chunks");
public static final SlimefunItemStack TABLE_SAW;
public static final SlimefunItemStack COMPOSTER = new SlimefunItemStack("COMPOSTER", Material.CAULDRON, "&aComposter", "", "&a&oCan convert various Materials over Time...");
public static final SlimefunItemStack ENHANCED_CRAFTING_TABLE = new SlimefunItemStack("ENHANCED_CRAFTING_TABLE", Material.CRAFTING_TABLE, "&eEnhanced Crafting Table", "", "&aA regular Crafting Table cannot", "&ahold this massive Amount of Power...");
public static final SlimefunItemStack CRUCIBLE = new SlimefunItemStack("CRUCIBLE", Material.CAULDRON, "&cCrucible", "", "&a&oUsed to smelt Items into Liquids");
public static final SlimefunItemStack JUICER = new SlimefunItemStack("JUICER", Material.GLASS_BOTTLE, "&aJuicer", "", "&aAllows you to create delicious Juice");
public static final ItemStack SOLAR_PANEL = new SlimefunItemStack("SOLAR_PANEL", Material.DAYLIGHT_DETECTOR, "&bSolar Panel", "", "&a&oTransforms Sunlight to Energy");
@Deprecated
public static final ItemStack DIGITAL_MINER = new CustomItem(Material.IRON_PICKAXE, "&bDigital Miner", "", "&4DEPRECATED", "&cThis machine will be removed at some point!", "&cWe don't know when.");
@Deprecated
public static final ItemStack ADVANCED_DIGITAL_MINER = new CustomItem(Material.DIAMOND_PICKAXE, "&6Advanced Digital Miner", "", "&4DEPRECATED", "&cThis machine will be removed at some point!", "&cWe don't know when.");
public static final SlimefunItemStack AUTOMATED_PANNING_MACHINE = new SlimefunItemStack("AUTOMATED_PANNING_MACHINE", Material.BOWL, "&eAutomated Panning Machine", "", "&rA MultiBlock Version of the Gold Pan", "&rand Nether Gold Pan combined in one machine.");
public static final SlimefunItemStack INDUSTRIAL_MINER = new SlimefunItemStack("INDUSTRIAL_MINER", Material.GOLDEN_PICKAXE, "&bIndustrial Miner", "", "&rThis Multiblock will mine any Ores", "&rin a 7x7 area underneath it.", "&rPlace coal or similar in its chest", "&rto fuel this machine.");
public static final SlimefunItemStack ADVANCED_INDUSTRIAL_MINER = new SlimefunItemStack("ADVANCED_INDUSTRIAL_MINER", Material.DIAMOND_PICKAXE, "&cAdvanced Industrial Miner", "", "&rThis Multiblock will mine any Ores", "&rin a 11x11 area underneath it.", "&rPlace a bucket of fuel or lava in", "", "&a+ Silk Touch", "&rits chest to fuel this machine.");
static {
ItemMeta meta = INDUSTRIAL_MINER.getItemMeta();
meta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES);
INDUSTRIAL_MINER.setItemMeta(meta);
ItemMeta meta2 = ADVANCED_INDUSTRIAL_MINER.getItemMeta();
meta2.addItemFlags(ItemFlag.HIDE_ATTRIBUTES);
ADVANCED_INDUSTRIAL_MINER.setItemMeta(meta2);
}
/* Machines */
public static final SlimefunItemStack COMPOSTER = new SlimefunItemStack("COMPOSTER", Material.CAULDRON, "&aComposter", "", "&a&oCan convert various Materials over Time...");
public static final SlimefunItemStack CRUCIBLE = new SlimefunItemStack("CRUCIBLE", Material.CAULDRON, "&cCrucible", "", "&a&oUsed to smelt Items into Liquids");
public static final SlimefunItemStack OUTPUT_CHEST = new SlimefunItemStack("OUTPUT_CHEST", Material.CHEST, "&4Output Chest", "", "&c&oA basic machine will try to put", "&c&oitems in this chest if it's placed", "&c&oadjacent to the dispenser.");
public static final SlimefunItemStack IGNITION_CHAMBER = new SlimefunItemStack("IGNITION_CHAMBER", Material.DROPPER, "&4Automatic Ignition Chamber", "", "&rPrevents the Smeltery from using up fire.", "&rJust fill it up with \"Flint and Steel\"", "&rand place it adjacent to the Smeltery's dispenser");
public static final SlimefunItemStack HOLOGRAM_PROJECTOR = new SlimefunItemStack("HOLOGRAM_PROJECTOR", Material.QUARTZ_SLAB, "&bHologram Projector", "", "&rProjects an Editable Hologram");
public static final ItemStack SOLAR_PANEL = new SlimefunItemStack("SOLAR_PANEL", Material.DAYLIGHT_DETECTOR, "&bSolar Panel", "", "&a&oTransforms Sunlight to Energy");
/* Enhanced Furnaces */
public static final SlimefunItemStack ENHANCED_FURNACE = new SlimefunItemStack("ENHANCED_FURNACE", Material.FURNACE, "&7Enhanced Furnace - &eI", "", "&7Processing Speed: &e1x", "&7Fuel Efficiency: &e1x", "&7Luck Multiplier: &e1x");

View File

@ -7,8 +7,8 @@ import org.bukkit.Material;
import org.bukkit.block.BlockFace;
import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.slimefun4.core.MultiBlock;
import io.github.thebusybiscuit.slimefun4.core.attributes.RecipeDisplayItem;
import io.github.thebusybiscuit.slimefun4.core.multiblocks.MultiBlock;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category;

View File

@ -204,11 +204,11 @@ public abstract class AGenerator extends AbstractEnergyGenerator {
}
private MachineFuel findRecipe(BlockMenu menu, Map<Integer, Integer> found) {
for (MachineFuel recipe : fuelTypes) {
for (MachineFuel fuel : fuelTypes) {
for (int slot : getInputSlots()) {
if (SlimefunUtils.isItemSimilar(menu.getItemInSlot(slot), recipe.getInput(), true)) {
found.put(slot, recipe.getInput().getAmount());
return recipe;
if (fuel.test(menu.getItemInSlot(slot))) {
found.put(slot, fuel.getInput().getAmount());
return fuel;
}
}
}

View File

@ -421,11 +421,11 @@ public abstract class AReactor extends AbstractEnergyGenerator {
}
private MachineFuel findRecipe(BlockMenu menu, Map<Integer, Integer> found) {
for (MachineFuel recipe : fuelTypes) {
for (MachineFuel fuel : fuelTypes) {
for (int slot : getInputSlots()) {
if (SlimefunUtils.isItemSimilar(menu.getItemInSlot(slot), recipe.getInput(), true)) {
found.put(slot, recipe.getInput().getAmount());
return recipe;
if (fuel.test(menu.getItemInSlot(slot))) {
found.put(slot, fuel.getInput().getAmount());
return fuel;
}
}
}

View File

@ -1,35 +1,57 @@
package me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems;
import java.util.function.Predicate;
import org.apache.commons.lang.Validate;
import org.bukkit.inventory.ItemStack;
public class MachineFuel {
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
import io.github.thebusybiscuit.slimefun4.utils.itemstack.ItemStackWrapper;
public class MachineFuel implements Predicate<ItemStack> {
private final int ticks;
private final ItemStack fuel;
private final ItemStack output;
// For performance optimizations
private final ItemStackWrapper wrapper;
public MachineFuel(int seconds, ItemStack fuel) {
this.ticks = seconds * 2;
this.fuel = fuel;
this.output = null;
this(seconds, fuel, null);
}
public MachineFuel(int seconds, ItemStack fuel, ItemStack output) {
Validate.notNull(fuel, "Fuel must never be null!");
Validate.isTrue(seconds > 0, "Fuel must last at least one second!");
this.ticks = seconds * 2;
this.fuel = fuel;
this.wrapper = new ItemStackWrapper(fuel);
this.output = output;
}
public ItemStack getInput() {
return this.fuel;
return fuel;
}
public ItemStack getOutput() {
return this.output;
return output;
}
/**
* This method returns how long this {@link MachineFuel} lasts.
* The result represents Slimefun ticks.
*
* @return How many ticks this fuel type lasts
*/
public int getTicks() {
return ticks;
}
@Override
public boolean test(ItemStack item) {
return SlimefunUtils.isItemSimilar(item, wrapper, true);
}
}

View File

@ -18,9 +18,9 @@ import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.cscorelib2.inventory.InvUtils;
import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction;
import io.github.thebusybiscuit.slimefun4.api.SlimefunAddon;
import io.github.thebusybiscuit.slimefun4.core.MultiBlock;
import io.github.thebusybiscuit.slimefun4.core.attributes.NotPlaceable;
import io.github.thebusybiscuit.slimefun4.core.attributes.RecipeDisplayItem;
import io.github.thebusybiscuit.slimefun4.core.multiblocks.MultiBlock;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category;

View File

@ -6,9 +6,8 @@ import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import io.github.thebusybiscuit.slimefun4.api.exceptions.IncompatibleItemHandlerException;
import io.github.thebusybiscuit.slimefun4.core.MultiBlock;
import io.github.thebusybiscuit.slimefun4.core.multiblocks.MultiBlock;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunMachine;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.multiblocks.MultiBlockMachine;
/**
@ -31,8 +30,7 @@ public interface MultiBlockInteractionHandler extends ItemHandler {
@Override
default Optional<IncompatibleItemHandlerException> validate(SlimefunItem item) {
// Change this to "MultiBlockMachine" once SlimefunMachine was removed or deprecated
if (!(item instanceof SlimefunMachine)) {
if (!(item instanceof MultiBlockMachine)) {
return Optional.of(new IncompatibleItemHandlerException("Only classes inheriting 'MultiBlockMachine' can have a MultiBlockInteractionHandler", item, this));
}

View File

@ -44,7 +44,7 @@ import io.github.thebusybiscuit.slimefun4.core.services.github.GitHubService;
import io.github.thebusybiscuit.slimefun4.core.services.metrics.MetricsService;
import io.github.thebusybiscuit.slimefun4.core.services.plugins.ThirdPartyPluginService;
import io.github.thebusybiscuit.slimefun4.implementation.items.altar.AncientAltar;
import io.github.thebusybiscuit.slimefun4.implementation.items.food.Cooler;
import io.github.thebusybiscuit.slimefun4.implementation.items.backpacks.Cooler;
import io.github.thebusybiscuit.slimefun4.implementation.items.tools.GrapplingHook;
import io.github.thebusybiscuit.slimefun4.implementation.items.weapons.SeismicAxe;
import io.github.thebusybiscuit.slimefun4.implementation.items.weapons.VampireBlade;

View File

@ -205,7 +205,7 @@ public class SlimefunItemStack extends CustomItem {
@Override
public String toString() {
return "SlimefunItemStack (" + id + ')';
return "SlimefunItemStack (" + id + (getAmount() > 1 ? (" x " + getAmount()) : "") + ')';
}
public Optional<String> getSkullTexture() {

View File

@ -16,11 +16,11 @@ commands:
reset-target: '&cYour Knowledge has been reset'
backpack:
description: Retrieve an existing backpack
invalid-id: '&4The backpack id must be a non-negative number!'
player-never-joined: '&4No player with that name has ever joined the server!'
backpack-does-not-exist: '&4That backpack does not exist!'
restored-backpack-given: '&bBackpack restored successfully! Added to your inventory!'
description: Retrieve a copy of an existing backpack
invalid-id: '&4The id must be a non-negative number!'
player-never-joined: '&4No player with that name could be found!'
backpack-does-not-exist: '&4The specified backpack does not exist!'
restored-backpack-given: '&aYour backpack has been restored and was added to your inventory!'
guide:
locked: 'LOCKED'
@ -202,7 +202,17 @@ machines:
CARGO_NODES:
must-be-placed: '&4Must be placed onto a chest or machine!'
INDUSTRIAL_MINER:
no-fuel: '&cYour Industrial Miner ran out of fuel! Put your fuel into the chest above.'
piston-facing: '&cYour Industrial Miner requires pistons to face upwards!'
piston-space: '&cThe two pistons need to have an empty block above them!'
destroyed: '&cYour Industrial Miner seems to have been destroyed.'
already-running: '&cThis Industrial Miner is already running!'
full-chest: '&cThe Chest of your Industrial Miner is full!'
no-permission: '&4You do not seem to have permission to operate an Industrial Miner here!'
finished: '&eYour Industrial Miner has finished! It obtained a total of %ores% ore(s)!'
anvil:
not-working: '&4You cannot use Slimefun Items in an anvil!'
@ -210,9 +220,6 @@ backpack:
already-open: '&cSorry, this Backpack is open somewhere else!'
no-stack: '&cYou cannot stack Backpacks'
miner:
no-ores: '&eSorry, I could not find any Ores nearby!'
workbench:
not-enhanced: '&4You cannot use Slimefun Items in a normal workbench'

View File

@ -231,3 +231,5 @@ slimefun:
kelp_cookie: Tasty Kelp
makeshift_smeltery: Improvised Smeltery
tree_growth_accelerator: Faster Trees
industrial_miner: Industrial Mining
advanced_industrial_miner: Better Mining

View File

@ -16,6 +16,15 @@ commands:
usage: You either forgot to install CS-CoreLib or you installed an unsupported version.
permissions:
slimefun.command.guide:
description: Allows you to obtain the Slimefun guide book
default: true
slimefun.command.search:
description: Allows you to do /sf search
default: true
slimefun.command.open_guide:
description: Allows you to open the SF guide without the book
default: op
slimefun.cheat.items:
description: Allows you to cheat Items
default: op
@ -40,15 +49,6 @@ permissions:
slimefun.command.backpack:
description: Allows you to do /sf backpack
default: op
slimefun.command.guide:
description: Allows you to obtain the Slimefun guide book
default: true
slimefun.command.search:
description: Allows you to do /sf search
default: true
slimefun.command.open_guide:
description: Allows you to open the SF guide without the book
default: op
slimefun.android.bypass:
description: Allows you to edit other Players Androids
default: op

View File

@ -6,6 +6,7 @@ import java.util.concurrent.atomic.AtomicReference;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Item;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
@ -28,13 +29,15 @@ import org.mockito.Mockito;
import be.seeseemelk.mockbukkit.MockBukkit;
import be.seeseemelk.mockbukkit.ServerMock;
import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
import io.github.thebusybiscuit.slimefun4.api.items.ItemState;
import io.github.thebusybiscuit.slimefun4.api.player.PlayerBackpack;
import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile;
import io.github.thebusybiscuit.slimefun4.implementation.items.backpacks.SlimefunBackpack;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.BackpackListener;
import io.github.thebusybiscuit.slimefun4.mocks.TestUtilities;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
public class TestBackpackListener {
@ -70,19 +73,16 @@ public class TestBackpackListener {
return ref.get();
}
private PlayerBackpack openMockBackpack(Player player, int size) throws InterruptedException {
ItemStack item = new CustomItem(Material.CHEST, "&4Mock Backpack", "", "&7Size: &e" + BACKPACK_SIZE, "&7ID: <ID>", "", "&7&eRight Click&7 to open");
private PlayerBackpack openMockBackpack(Player player, String id, int size) throws InterruptedException {
SlimefunItemStack item = new SlimefunItemStack(id, Material.CHEST, "&4Mock Backpack", "", "&7Size: &e" + BACKPACK_SIZE, "&7ID: <ID>", "", "&7&eRight Click&7 to open");
PlayerProfile profile = TestUtilities.awaitProfile(player);
PlayerBackpack backpack = profile.createBackpack(size);
listener.setBackpackId(player, item, 2, backpack.getId());
SlimefunBackpack slimefunBackpack = Mockito.mock(SlimefunBackpack.class);
Mockito.when(slimefunBackpack.getSize()).thenReturn(size);
// This will make hasUnlocked() immediately pass
Mockito.when(slimefunBackpack.getState()).thenReturn(ItemState.VANILLA_FALLBACK);
SlimefunPlugin.getRegistry().getEnabledSlimefunItems().add(slimefunBackpack);
Category category = new Category(new NamespacedKey(plugin, "test_backpacks"), new CustomItem(Material.CHEST, "&4Test Backpacks"));
SlimefunBackpack slimefunBackpack = new SlimefunBackpack(size, category, item, RecipeType.NULL, new ItemStack[9]);
slimefunBackpack.register(plugin);
listener.openBackpack(player, item, slimefunBackpack);
return backpack;
@ -118,7 +118,7 @@ public class TestBackpackListener {
@Test
public void testOpenBackpack() throws InterruptedException {
Player player = server.addPlayer();
PlayerBackpack backpack = openMockBackpack(player, 27);
PlayerBackpack backpack = openMockBackpack(player, "TEST_OPEN_BACKPACK", 27);
InventoryView view = player.getOpenInventory();
Assertions.assertEquals(backpack.getInventory(), view.getTopInventory());
}
@ -126,7 +126,7 @@ public class TestBackpackListener {
@Test
public void testCloseBackpack() throws InterruptedException {
Player player = server.addPlayer();
PlayerBackpack backpack = openMockBackpack(player, 27);
PlayerBackpack backpack = openMockBackpack(player, "TEST_CLOSE_BACKPACK", 27);
listener.onClose(new InventoryCloseEvent(player.getOpenInventory()));
Assertions.assertTrue(backpack.getOwner().isDirty());
@ -135,7 +135,7 @@ public class TestBackpackListener {
@Test
public void testBackpackDropNormalItem() throws InterruptedException {
Player player = server.addPlayer();
openMockBackpack(player, 27);
openMockBackpack(player, "DROP_NORMAL_ITEM_BACKPACK_TEST", 27);
Item item = Mockito.mock(Item.class);
Mockito.when(item.getItemStack()).thenReturn(new ItemStack(Material.SUGAR_CANE));
@ -145,9 +145,9 @@ public class TestBackpackListener {
Assertions.assertFalse(event.isCancelled());
}
private boolean isAllowed(ItemStack item) throws InterruptedException {
private boolean isAllowed(String id, ItemStack item) throws InterruptedException {
Player player = server.addPlayer();
Inventory inv = openMockBackpack(player, 9).getInventory();
Inventory inv = openMockBackpack(player, id, 9).getInventory();
int slot = 7;
inv.setItem(slot, item);
@ -159,20 +159,20 @@ public class TestBackpackListener {
@ParameterizedTest
@EnumSource(value = Material.class, names = { "AIR", "DIAMOND", "STONE" })
public void areItemsAllowed(Material type) throws InterruptedException {
Assertions.assertTrue(isAllowed(new ItemStack(type)));
Assertions.assertTrue(isAllowed("BACKPACK_ALLOWANCE_" + type.name(), new ItemStack(type)));
}
@ParameterizedTest
@EnumSource(value = Material.class, names = { "SHULKER_BOX", "RED_SHULKER_BOX", "BLUE_SHULKER_BOX", "BLACK_SHULKER_BOX" })
public void areShulkerBoxesAllowed(Material type) throws InterruptedException {
Assertions.assertFalse(isAllowed(new ItemStack(type)));
Assertions.assertFalse(isAllowed("BACKPACK_ALLOWANCE_" + type.name(), new ItemStack(type)));
}
@ParameterizedTest
@EnumSource(value = Material.class, names = { "AIR", "SHULKER_BOX" })
public void testHotbarKey(Material type) throws InterruptedException {
Player player = server.addPlayer();
openMockBackpack(player, 9);
openMockBackpack(player, "BACKPACK_HOTBAR_" + type.name(), 9);
int slot = 7;
player.getInventory().setItem(slot, new ItemStack(type));

View File

@ -18,7 +18,7 @@ import be.seeseemelk.mockbukkit.MockBukkit;
import be.seeseemelk.mockbukkit.ServerMock;
import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
import io.github.thebusybiscuit.slimefun4.api.events.MultiBlockInteractEvent;
import io.github.thebusybiscuit.slimefun4.core.MultiBlock;
import io.github.thebusybiscuit.slimefun4.core.multiblocks.MultiBlock;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.MultiBlockListener;
import io.github.thebusybiscuit.slimefun4.mocks.TestUtilities;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;

View File

@ -10,7 +10,7 @@ import org.junit.jupiter.api.Test;
import be.seeseemelk.mockbukkit.MockBukkit;
import be.seeseemelk.mockbukkit.ServerMock;
import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
import io.github.thebusybiscuit.slimefun4.core.MultiBlock;
import io.github.thebusybiscuit.slimefun4.core.multiblocks.MultiBlock;
import io.github.thebusybiscuit.slimefun4.mocks.TestUtilities;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;