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

Auto-Crafters can now be turned on and off via the gui

This commit is contained in:
TheBusyBiscuit 2021-03-27 22:26:15 +01:00
parent 235d3f4d57
commit fd16306b61
7 changed files with 137 additions and 28 deletions

View File

@ -30,6 +30,7 @@
* Added "Smart-Filling" mode to Cargo Input nodes
* Added "Netherite Ingot -> Netherite Block" recipe to Electric Press
* Added Armor Forge Auto Crafter
* Auto-Crafters can now be turned on and off
#### Changes
* Removed all functionality from the old Automated Crafting Chamber

View File

@ -9,7 +9,6 @@ import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
import org.apache.commons.lang.Validate;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
@ -35,6 +34,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.AutoCrafterListener;
import io.github.thebusybiscuit.slimefun4.implementation.tasks.AsyncRecipeChoiceTask;
import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils;
import io.github.thebusybiscuit.slimefun4.utils.HeadTexture;
import io.github.thebusybiscuit.slimefun4.utils.tags.SlimefunTag;
import io.papermc.lib.PaperLib;
import io.papermc.lib.features.blockstatesnapshot.BlockStateSnapshotResult;
@ -73,6 +73,11 @@ public abstract class AbstractAutoCrafter extends SlimefunItem implements Energy
*/
protected final NamespacedKey recipeStorageKey;
/**
* The {@link NamespacedKey} used to determine whether the recipe is enabled.
*/
protected final NamespacedKey recipeEnabledKey;
// @formatter:off
protected final int[] background = {
0, 1, 2, 3, 4, 5, 6, 7, 8,
@ -88,6 +93,7 @@ public abstract class AbstractAutoCrafter extends SlimefunItem implements Energy
super(category, item, recipeType, recipe);
recipeStorageKey = new NamespacedKey(SlimefunPlugin.instance(), "recipe_key");
recipeEnabledKey = new NamespacedKey(SlimefunPlugin.instance(), "recipe_enabled");
addItemHandler(new BlockTicker() {
@ -142,19 +148,28 @@ public abstract class AbstractAutoCrafter extends SlimefunItem implements Energy
}
}
/**
* This method performs one tick for the {@link AbstractAutoCrafter}.
*
* @param b
* The block for this {@link AbstractAutoCrafter}
* @param data
* The data stored on this block
*/
protected void tick(@Nonnull Block b, @Nonnull Config data) {
AbstractRecipe recipe = getSelectedRecipe(b);
if (recipe == null || getCharge(b.getLocation(), data) < getEnergyConsumption()) {
// No valid recipe selected, abort...
if (recipe == null || !recipe.isEnabled() || getCharge(b.getLocation(), data) < getEnergyConsumption()) {
// No recipe / disabled recipe / no energy, abort...
return;
}
Block chest = b.getRelative(BlockFace.DOWN);
// The block below where we would expect our inventory holder.
Block targetBlock = b.getRelative(BlockFace.DOWN);
// Make sure this is a Chest
if (isValidInventory(chest)) {
BlockState state = PaperLib.getBlockState(chest, false).getState();
if (isValidInventory(targetBlock)) {
BlockState state = PaperLib.getBlockState(targetBlock, false).getState();
if (state instanceof InventoryHolder) {
Inventory inv = ((InventoryHolder) state).getInventory();
@ -236,6 +251,9 @@ public abstract class AbstractAutoCrafter extends SlimefunItem implements Energy
if (recipe == null) {
// Clear the value from persistent data storage
PersistentDataAPI.remove((Skull) state, recipeStorageKey);
// Also remove the "enabled" state since this should be per-recipe.
PersistentDataAPI.remove((Skull) state, recipeEnabledKey);
} else {
// Store the value to persistent data storage
PersistentDataAPI.setString((Skull) state, recipeStorageKey, recipe.toString());
@ -271,14 +289,29 @@ public abstract class AbstractAutoCrafter extends SlimefunItem implements Energy
ChestMenuUtils.drawBackground(menu, background);
ChestMenuUtils.drawBackground(menu, 45, 46, 47, 48, 50, 51, 52, 53);
menu.addItem(49, new CustomItem(Material.BARRIER, ChatColor.RED + SlimefunPlugin.getLocalization().getMessage(p, "messages.auto-crafting.remove")));
menu.addMenuClickHandler(49, (pl, item, slot, action) -> {
setSelectedRecipe(b, null);
pl.closeInventory();
p.playSound(p.getLocation(), Sound.UI_BUTTON_CLICK, 1, 1);
SlimefunPlugin.getLocalization().sendMessage(p, "messages.auto-crafting.recipe-removed");
return false;
});
if (recipe.isEnabled()) {
menu.addItem(49, new CustomItem(Material.BARRIER, SlimefunPlugin.getLocalization().getMessages(p, "messages.auto-crafting.tooltips.enabled")));
menu.addMenuClickHandler(49, (pl, item, slot, action) -> {
if (action.isRightClicked()) {
deleteRecipe(pl, b);
} else {
setRecipeEnabled(pl, b, false);
}
return false;
});
} else {
menu.addItem(49, new CustomItem(HeadTexture.EXCLAMATION_MARK.getAsItemStack(), SlimefunPlugin.getLocalization().getMessages(p, "messages.auto-crafting.tooltips.disabled")));
menu.addMenuClickHandler(49, (pl, item, slot, action) -> {
if (action.isRightClicked()) {
deleteRecipe(pl, b);
} else {
setRecipeEnabled(pl, b, true);
}
return false;
});
}
// This makes the slots cycle through different ingredients
AsyncRecipeChoiceTask task = new AsyncRecipeChoiceTask();
@ -293,6 +326,32 @@ public abstract class AbstractAutoCrafter extends SlimefunItem implements Energy
}
}
@ParametersAreNonnullByDefault
private void setRecipeEnabled(Player p, Block b, boolean enabled) {
p.closeInventory();
p.playSound(p.getLocation(), Sound.UI_BUTTON_CLICK, 1, 1);
BlockState state = PaperLib.getBlockState(b, false).getState();
// Make sure the block is still a Skull
if (state instanceof Skull) {
if (enabled) {
PersistentDataAPI.remove((Skull) state, recipeEnabledKey);
SlimefunPlugin.getLocalization().sendMessage(p, "messages.auto-crafting.re-enabled");
} else {
PersistentDataAPI.setByte((Skull) state, recipeEnabledKey, (byte) 1);
SlimefunPlugin.getLocalization().sendMessage(p, "messages.auto-crafting.temporarily-disabled");
}
}
}
@ParametersAreNonnullByDefault
private void deleteRecipe(Player p, Block b) {
setSelectedRecipe(b, null);
p.closeInventory();
p.playSound(p.getLocation(), Sound.UI_BUTTON_CLICK, 1, 1);
SlimefunPlugin.getLocalization().sendMessage(p, "messages.auto-crafting.recipe-removed");
}
/**
* This method checks whether the given {@link Predicate} matches the provided {@link ItemStack}.
*

View File

@ -44,6 +44,11 @@ public abstract class AbstractRecipe {
*/
private final ItemStack result;
/**
* Whether this recipe is enabled.
*/
private boolean enabled;
/**
* Protected constructor. For implementation classes only.
*
@ -83,6 +88,27 @@ public abstract class AbstractRecipe {
return result;
}
/**
* This returns whether or not this recipe has been enabled.
* A disabled recipe will not be crafted.
*
* @return Whether this recipe is enabled
*/
public boolean isEnabled() {
return enabled;
}
/**
* This method enables or disables this recipe.
* A disabled recipe will not be crafted.
*
* @param enabled
* Whether this recipe is enabled
*/
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
/**
* This will visually represent this {@link AbstractRecipe} in the given {@link ChestMenu}.
* Any {@link MaterialChoice} will be cycled through using the {@link AsyncRecipeChoiceTask}.

View File

@ -13,8 +13,9 @@ import org.bukkit.block.BlockState;
import org.bukkit.block.Skull;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataType;
import io.github.thebusybiscuit.cscorelib2.data.PersistentDataAPI;
import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.tasks.AsyncRecipeChoiceTask;
@ -60,11 +61,15 @@ public class SlimefunAutoCrafter extends AbstractAutoCrafter {
if (state instanceof Skull) {
// Read the stored value from persistent data storage
String value = PersistentDataAPI.getString((Skull) state, recipeStorageKey);
PersistentDataContainer container = ((Skull) state).getPersistentDataContainer();
String value = container.get(recipeStorageKey, PersistentDataType.STRING);
SlimefunItem item = SlimefunItem.getByID(value);
if (item != null) {
return AbstractRecipe.of(item, targetRecipeType);
boolean enabled = !container.has(recipeEnabledKey, PersistentDataType.BYTE);
AbstractRecipe recipe = AbstractRecipe.of(item, targetRecipeType);
recipe.setEnabled(enabled);
return recipe;
}
}

View File

@ -21,8 +21,9 @@ import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.Recipe;
import org.bukkit.inventory.ShapedRecipe;
import org.bukkit.inventory.ShapelessRecipe;
import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataType;
import io.github.thebusybiscuit.cscorelib2.data.PersistentDataAPI;
import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
import io.github.thebusybiscuit.slimefun4.core.services.MinecraftRecipeService;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
@ -58,16 +59,12 @@ public class VanillaAutoCrafter extends AbstractAutoCrafter {
@Override
@Nullable
public AbstractRecipe getSelectedRecipe(@Nonnull Block b) {
return AbstractRecipe.of(getRecipe(b));
}
@Nullable
private Recipe getRecipe(@Nonnull Block b) {
BlockState state = PaperLib.getBlockState(b, false).getState();
if (state instanceof Skull) {
// Read the stored value from persistent data storage
String value = PersistentDataAPI.getString((Skull) state, recipeStorageKey);
PersistentDataContainer container = ((Skull) state).getPersistentDataContainer();
String value = container.get(recipeStorageKey, PersistentDataType.STRING);
if (value != null) {
String[] values = PatternUtils.COLON.split(value);
@ -79,8 +76,15 @@ public class VanillaAutoCrafter extends AbstractAutoCrafter {
*/
@SuppressWarnings("deprecation")
NamespacedKey key = new NamespacedKey(values[0], values[1]);
Recipe keyedRecipe = SlimefunPlugin.getMinecraftRecipeService().getRecipe(key);
return SlimefunPlugin.getMinecraftRecipeService().getRecipe(key);
if (keyedRecipe != null) {
boolean enabled = !container.has(recipeEnabledKey, PersistentDataType.BYTE);
AbstractRecipe recipe = AbstractRecipe.of(keyedRecipe);
recipe.setEnabled(enabled);
return recipe;
}
}
}

View File

@ -115,7 +115,8 @@ public enum HeadTexture {
NECROTIC_SKULL("7953b6c68448e7e6b6bf8fb273d7203acd8e1be19e81481ead51f45de59a8"),
VANILLA_AUTO_CRAFTER("80a4334f6a61e40c0c63deb665fa7b581e6eb259f7a3207ced7a1ff8bdc8a9f9"),
ENHANCED_AUTO_CRAFTER("5038298306a5e28584df39e88896917c38d40a326226d8c83070723c95798b24"),
ARMOR_AUTO_CRAFTER("5cbd9f5ec1ed007259996491e69ff649a3106cf920227b1bb3a71ee7a89863f");
ARMOR_AUTO_CRAFTER("5cbd9f5ec1ed007259996491e69ff649a3106cf920227b1bb3a71ee7a89863f"),
EXCLAMATION_MARK("2e3f50ba62cbda3ecf5479b62fedebd61d76589771cc19286bf2745cd71e47c6");
private final String texture;
private final UUID uuid;

View File

@ -151,9 +151,22 @@ messages:
recipe-set: '&aYou have successfully set the recipe for this machine.'
recipe-removed: '&eYou have successfully removed the recipe from this machine. You can set a new recipe at any time!'
no-recipes: '&cWe could not find any valid recipes for the item you are holding.'
missing-chest: '&cMissing chest! Auto Crafters need to be placed above a chest.'
missing-chest: '&cMissing chest! Auto-Crafters need to be placed above a chest.'
select: 'Select this recipe'
remove: 'Remove this recipe'
temporarily-disabled: '&eThis Auto-Crafter was temporarily disabled. You can re-enable it at any time!'
re-enabled: '&eThis Auto-Crafter was re-enabled!'
tooltips:
enabled:
- '&aThis recipe is currently enabled'
- ''
- '&eLeft Click &7to temporarily disable the recipe'
- '&eRight Click &7to remove this recipe'
disabled:
- '&cThis recipe is currently disabled'
- ''
- '&eLeft Click &7to re-enable this recipe'
- '&eRight Click &7to remove this recipe'
talisman:
anvil: '&a&oYour Talisman saved your tool from breaking'