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:
commit
b659e51008
@ -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
|
||||
|
2
pom.xml
2
pom.xml
@ -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>
|
||||
|
@ -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}.
|
||||
|
@ -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;
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
}
|
@ -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;
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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 -> {
|
||||
|
@ -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)));
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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));
|
||||
}
|
||||
|
||||
}
|
@ -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");
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
@ -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++) {
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
@ -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) {
|
||||
|
@ -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)})
|
||||
|
@ -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");
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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() {
|
||||
|
@ -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'
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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));
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user