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:
parent
235d3f4d57
commit
fd16306b61
@ -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
|
||||
|
@ -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")));
|
||||
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) -> {
|
||||
setSelectedRecipe(b, null);
|
||||
pl.closeInventory();
|
||||
p.playSound(p.getLocation(), Sound.UI_BUTTON_CLICK, 1, 1);
|
||||
SlimefunPlugin.getLocalization().sendMessage(p, "messages.auto-crafting.recipe-removed");
|
||||
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}.
|
||||
*
|
||||
|
@ -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}.
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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'
|
||||
|
Loading…
Reference in New Issue
Block a user