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

Added Produce Collector to automate Milk and Mushroom Stew

Also fixed Auto Crafters not handling milk buckets properly
And allowed Block Placers to place down cakes
This commit is contained in:
TheBusyBiscuit 2021-03-28 01:40:19 +01:00
parent 73b5ef8b52
commit 0dc1ac3894
12 changed files with 249 additions and 18 deletions

View File

@ -31,6 +31,8 @@
* Added "Netherite Ingot -> Netherite Block" recipe to Electric Press
* Added Armor Forge Auto Crafter
* Auto-Crafters can now be turned on and off
* Added Produce Collector to automate Milk and Mushroom Stew
* Block Placers can now place down cake
#### Changes
* Removed all functionality from the old Automated Crafting Chamber
@ -48,6 +50,7 @@
* Fixed #2903
* Fixed #2913
* Fixed #2914
* Fixed Auto Crafters swallowing buckets when crafting cake
## Release Candidate 21 (14 Mar 2021)
https://thebusybiscuit.github.io/builds/TheBusyBiscuit/Slimefun4/stable/#21

View File

@ -3,6 +3,7 @@ package io.github.thebusybiscuit.slimefun4.api.events;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
@ -26,7 +27,7 @@ public class AsyncMachineProcessCompleteEvent extends Event {
private final MachineRecipe machineRecipe;
public AsyncMachineProcessCompleteEvent(@Nonnull Location l, @Nullable AContainer container, @Nullable MachineRecipe machineRecipe) {
super(true);
super(!Bukkit.isPrimaryThread());
this.location = l;
this.container = container;

View File

@ -782,7 +782,9 @@ public final class SlimefunItems {
public static final SlimefunItemStack CARGO_OUTPUT_NODE = new SlimefunItemStack("CARGO_NODE_OUTPUT", HeadTexture.CARGO_OUTPUT_NODE, "&7Cargo Node &c(Output)", "", "&fCargo Output Pipe");
public static final SlimefunItemStack CARGO_OUTPUT_NODE_2 = new SlimefunItemStack("CARGO_NODE_OUTPUT_ADVANCED", HeadTexture.CARGO_OUTPUT_NODE, "&6Advanced Cargo Node &c(Output)", "", "&fCargo Output Pipe");
// Animal farm
public static final SlimefunItemStack AUTO_BREEDER = new SlimefunItemStack("AUTO_BREEDER", Material.HAY_BLOCK, "&eAuto-Breeder", "", "&fRuns on &aOrganic Food", "", LoreBuilder.machine(MachineTier.END_GAME, MachineType.MACHINE), LoreBuilder.powerBuffer(1024), "&8\u21E8 &e\u26A1 &760 J/Animal");
public static final SlimefunItemStack PRODUCE_COLLECTOR = new SlimefunItemStack("PRODUCE_COLLECTOR", Material.HAY_BLOCK, "&bProduce Collector", "", "&fThis machine allows you to", "&fcollect produce from nearby animals.", "", LoreBuilder.machine(MachineTier.ADVANCED, MachineType.MACHINE), LoreBuilder.powerBuffer(512), LoreBuilder.powerPerSecond(32));
public static final SlimefunItemStack ORGANIC_FOOD = new SlimefunItemStack("ORGANIC_FOOD", HeadTexture.FILLED_CAN, "&aOrganic Food", "&7Content: &9???");
public static final SlimefunItemStack WHEAT_ORGANIC_FOOD = new SlimefunItemStack("ORGANIC_FOOD_WHEAT", HeadTexture.FILLED_CAN, ORGANIC_FOOD.getDisplayName(), "&7Content: &9Wheat");

View File

@ -24,6 +24,7 @@ import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.cscorelib2.data.PersistentDataAPI;
import io.github.thebusybiscuit.cscorelib2.inventory.ItemUtils;
import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction;
import io.github.thebusybiscuit.slimefun4.api.SlimefunAddon;
@ -428,7 +429,9 @@ public abstract class AbstractAutoCrafter extends SlimefunItem implements Energy
// Double-check to be extra safe
if (item != null) {
item.setAmount(entry.getValue());
// Consume the difference
int toRemove = item.getAmount() - entry.getValue();
ItemUtils.consumeItem(item, toRemove, true);
}
}

View File

@ -13,6 +13,7 @@ import org.bukkit.Material;
import org.bukkit.Nameable;
import org.bukkit.OfflinePlayer;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.Dispenser;
import org.bukkit.entity.Player;
import org.bukkit.event.block.BlockPlaceEvent;
@ -97,16 +98,7 @@ public class BlockPlacer extends SlimefunItem {
e.setCancelled(true);
if (!material.isBlock() || SlimefunTag.BLOCK_PLACER_IGNORED_MATERIALS.isTagged(material)) {
/*
* Some materials cannot be reliably placed, like beds,
* it would look kinda wonky, so we just ignore these altogether.
* The event has already been cancelled too, so they won't drop.
*/
return;
}
if (facedBlock.isEmpty() && isAllowed(material) && dispenser.getInventory().getViewers().isEmpty()) {
if (facedBlock.isEmpty() && dispenser.getInventory().getViewers().isEmpty() && isAllowed(facedBlock, material)) {
SlimefunItem item = SlimefunItem.getByItem(e.getItem());
if (item != null) {
@ -158,14 +150,33 @@ public class BlockPlacer extends SlimefunItem {
*
* @return Whether placing this {@link Material} is allowed
*/
private boolean isAllowed(@Nonnull Material type) {
for (String blockType : unplaceableBlocks.getValue()) {
if (type.toString().equals(blockType)) {
return false;
private boolean isAllowed(@Nonnull Block facedBlock, @Nonnull Material type) {
if (!type.isBlock()) {
// Make sure the material is actually a block.
return false;
} else if (type == Material.CAKE) {
/*
* Special case for cakes.
* Cakes are a lie but I really want the Block Placer to place them down!!!
*/
return !facedBlock.getRelative(BlockFace.DOWN).isPassable();
} else if (SlimefunTag.BLOCK_PLACER_IGNORED_MATERIALS.isTagged(type)) {
/*
* Some materials cannot be reliably placed, like beds,
* it would look kinda wonky, so we just ignore these altogether.
* The event has already been cancelled too, so they won't drop.
*/
return false;
} else {
// Check for all unplaceable block
for (String blockType : unplaceableBlocks.getValue()) {
if (type.toString().equals(blockType)) {
return false;
}
}
}
return true;
return true;
}
}
@ParametersAreNonnullByDefault

View File

@ -3,6 +3,8 @@ package io.github.thebusybiscuit.slimefun4.implementation.items.electric.machine
import java.util.ArrayList;
import java.util.List;
import javax.annotation.ParametersAreNonnullByDefault;
import org.bukkit.Material;
import org.bukkit.Tag;
import org.bukkit.inventory.ItemStack;
@ -27,6 +29,7 @@ public class AutoDrier extends AContainer implements RecipeDisplayItem, NotHoppe
private List<ItemStack> recipeList;
@ParametersAreNonnullByDefault
public AutoDrier(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(category, item, recipeType, recipe);
}

View File

@ -1,5 +1,7 @@
package io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines;
import javax.annotation.ParametersAreNonnullByDefault;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
@ -13,6 +15,7 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
public class CarbonPress extends AContainer implements RecipeDisplayItem {
@ParametersAreNonnullByDefault
public CarbonPress(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(category, item, recipeType, recipe);
}

View File

@ -0,0 +1,39 @@
package io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.entities;
import java.util.function.Predicate;
import javax.annotation.Nonnull;
import javax.annotation.ParametersAreNonnullByDefault;
import org.apache.commons.lang.Validate;
import org.bukkit.entity.LivingEntity;
import org.bukkit.inventory.ItemStack;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.MachineRecipe;
/**
* An {@link AnimalProduce} can be obtained via the {@link ProduceCollector}.
*
* @author TheBusyBiscuit
*
* @see ProduceCollector
*
*/
public class AnimalProduce extends MachineRecipe implements Predicate<LivingEntity> {
private final Predicate<LivingEntity> predicate;
@ParametersAreNonnullByDefault
public AnimalProduce(ItemStack input, Predicate<LivingEntity> predicate, ItemStack result) {
super(5, new ItemStack[] { input }, new ItemStack[] { result });
Validate.notNull(predicate, "The Predicate must not be null");
this.predicate = predicate;
}
@Override
public boolean test(@Nonnull LivingEntity entity) {
return predicate.test(entity);
}
}

View File

@ -0,0 +1,156 @@
package io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.entities;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.Predicate;
import javax.annotation.Nonnull;
import javax.annotation.ParametersAreNonnullByDefault;
import org.apache.commons.lang.Validate;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Ageable;
import org.bukkit.entity.Cow;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.MushroomCow;
import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.cscorelib2.inventory.InvUtils;
import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting;
import io.github.thebusybiscuit.slimefun4.api.items.settings.IntRangeSetting;
import io.github.thebusybiscuit.slimefun4.core.attributes.RecipeDisplayItem;
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config;
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AContainer;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.MachineRecipe;
import me.mrCookieSlime.Slimefun.Objects.handlers.BlockTicker;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu;
/**
* The {@link ProduceCollector} allows you to collect produce from animals.
* Providing it with a bucket and a nearby {@link Cow} will allow you to obtain milk.
*
* @author TheBusyBiscuit
*
*/
public class ProduceCollector extends AContainer implements RecipeDisplayItem {
private final Set<AnimalProduce> animalProduces = new HashSet<>();
private final ItemSetting<Integer> range = new IntRangeSetting(this, "range", 1, 2, 32);
@ParametersAreNonnullByDefault
public ProduceCollector(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(category, item, recipeType, recipe);
addItemSetting(range);
}
@Override
protected void registerDefaultRecipes() {
addProduce(new AnimalProduce(new ItemStack(Material.BUCKET), Cow.class::isInstance, new ItemStack(Material.MILK_BUCKET)));
addProduce(new AnimalProduce(new ItemStack(Material.BOWL), MushroomCow.class::isInstance, new ItemStack(Material.MUSHROOM_STEW)));
}
/**
* This method adds a new {@link AnimalProduce} to this machine.
*
* @param produce
* The {@link AnimalProduce} to add
*/
public void addProduce(@Nonnull AnimalProduce produce) {
Validate.notNull(produce, "A produce cannot be null");
this.animalProduces.add(produce);
}
@Override
public void preRegister() {
addItemHandler(new BlockTicker() {
@Override
public void tick(Block b, SlimefunItem sf, Config data) {
ProduceCollector.this.tick(b);
}
@Override
public boolean isSynchronized() {
// We override the preRegister() method to override the sync setting here
return true;
}
});
}
@Override
public List<ItemStack> getDisplayRecipes() {
List<ItemStack> displayRecipes = new ArrayList<>();
displayRecipes.add(new CustomItem(Material.BUCKET, null, "&fRequires &bCow &fnearby"));
displayRecipes.add(new ItemStack(Material.MILK_BUCKET));
displayRecipes.add(new CustomItem(Material.BOWL, null, "&fRequires &bMooshroom &fnearby"));
displayRecipes.add(new ItemStack(Material.MUSHROOM_STEW));
return displayRecipes;
}
@Override
protected MachineRecipe findNextRecipe(@Nonnull BlockMenu inv) {
for (int slot : getInputSlots()) {
for (AnimalProduce produce : animalProduces) {
ItemStack item = inv.getItemInSlot(slot);
if (!SlimefunUtils.isItemSimilar(item, produce.getInput()[0], true) || !InvUtils.fits(inv.toInventory(), produce.getOutput()[0], getOutputSlots())) {
continue;
}
if (isAnimalNearby(inv.getBlock(), produce::test)) {
inv.consumeItem(slot);
return produce;
}
}
}
return null;
}
@ParametersAreNonnullByDefault
private boolean isAnimalNearby(Block b, Predicate<LivingEntity> predicate) {
int radius = range.getValue();
return !b.getWorld().getNearbyEntities(b.getLocation(), radius, radius, radius, n -> isValidAnimal(n, predicate)).isEmpty();
}
@ParametersAreNonnullByDefault
private boolean isValidAnimal(Entity n, Predicate<LivingEntity> predicate) {
if (n instanceof LivingEntity) {
if (n instanceof Ageable && !((Ageable) n).isAdult()) {
// We only take adults into consideration
return false;
} else {
return predicate.test((LivingEntity) n);
}
} else {
return false;
}
}
@Override
public String getMachineIdentifier() {
return "PRODUCE_COLLECTOR";
}
@Override
public ItemStack getProgressBar() {
return new ItemStack(Material.SHEARS);
}
}

View File

@ -282,6 +282,7 @@ public final class ResearchSetup {
register("wise_talisman", 271, "Talisman of the Wise", 20, SlimefunItems.TALISMAN_WISE);
register("book_binder", 272, "Enchantment Book Binding", 26, SlimefunItems.BOOK_BINDER);
register("auto_crafting", 273, "Automatic Crafting", 30, SlimefunItems.VANILLA_AUTO_CRAFTER, SlimefunItems.ENHANCED_AUTO_CRAFTER, SlimefunItems.ARMOR_AUTO_CRAFTER);
register("produce_collector", 274, "Automatic Milking", 20, SlimefunItems.PRODUCE_COLLECTOR);
}
@ParametersAreNonnullByDefault

View File

@ -112,6 +112,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.enchanting.BookBinder;
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.entities.ExpCollector;
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.entities.IronGolemAssembler;
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.entities.ProduceCollector;
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.entities.WitherAssembler;
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.reactors.NetherStarReactor;
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.reactors.NuclearReactor;
@ -2604,6 +2605,13 @@ public final class SlimefunItemSetup {
.setEnergyConsumption(32)
.register(plugin);
new ProduceCollector(categories.electricity, SlimefunItems.PRODUCE_COLLECTOR, RecipeType.ENHANCED_CRAFTING_TABLE,
new ItemStack[] {})
.setCapacity(256)
.setProcessingSpeed(1)
.setEnergyConsumption(16)
.register(plugin);
// @formatter:on
}

View File

@ -250,3 +250,4 @@ slimefun:
bee_armor: Bee Armor
book_binder: Enchantment Book Binding
auto_crafting: Automatic Crafting
produce_collector: Automatic Milking