Added Super Shaped recipes. **Requires MythicLib Update** to access super workbench with /swb

This commit is contained in:
Gunging 2021-07-31 21:03:32 -04:00
parent 246235e655
commit 510417c9aa
15 changed files with 606 additions and 70 deletions

View File

@ -5,10 +5,7 @@ import io.lumine.mythic.utils.items.ItemFactory;
import net.Indyuce.mmoitems.api.item.template.MMOItemTemplate;
import net.Indyuce.mmoitems.api.util.message.FFPMMOItems;
import net.Indyuce.mmoitems.gui.edition.EditionInventory;
import net.Indyuce.mmoitems.gui.edition.recipe.registry.RMGRR_Shaped;
import net.Indyuce.mmoitems.gui.edition.recipe.registry.RMGRR_Shapeless;
import net.Indyuce.mmoitems.gui.edition.recipe.registry.RMGRR_Smithing;
import net.Indyuce.mmoitems.gui.edition.recipe.registry.RecipeRegistry;
import net.Indyuce.mmoitems.gui.edition.recipe.registry.*;
import net.Indyuce.mmoitems.gui.edition.recipe.registry.burninglegacy.RMGRR_LBBlast;
import net.Indyuce.mmoitems.gui.edition.recipe.registry.burninglegacy.RMGRR_LBCampfire;
import net.Indyuce.mmoitems.gui.edition.recipe.registry.burninglegacy.RMGRR_LBFurnace;
@ -233,6 +230,7 @@ public class RecipeBrowserGUI extends EditionInventory {
registerRecipe(new RMGRR_Smithing());
registerRecipe(new RMGRR_Shapeless());
registerRecipe(new RMGRR_Shaped());
registerRecipe(new RMGRR_SuperShaped());
/*
* These don't go through mythiclib, I, gunging, merely
@ -241,7 +239,7 @@ public class RecipeBrowserGUI extends EditionInventory {
*
* After the RMGRR_LegacyBurning.sendToMythicLib method (that
* sends the recipes back to RecipeManager.registerBurningRecipe)
* I have no clue what happens; didn't even read that far.
* I have no clue what happens; barely even read that far.
*/
registerRecipe(new RMGRR_LBFurnace());
registerRecipe(new RMGRR_LBBlast());

View File

@ -55,7 +55,7 @@ public class RMGRI_BurningLegacy implements RMG_RecipeInterpreter{
}
@Override
public void editInput(@NotNull ConfigurationSection section, @NotNull ProvidedUIFilter input, int slot) {
public void editInput(@NotNull ProvidedUIFilter input, int slot) {
if (slot != 0) { return; }
@ -66,11 +66,11 @@ public class RMGRI_BurningLegacy implements RMG_RecipeInterpreter{
section.set(ITEM, input.toString());
}
@Override public void editOutput(@NotNull ConfigurationSection section, @NotNull ProvidedUIFilter input, int slot) { }
@Override public void editOutput(@NotNull ProvidedUIFilter input, int slot) { }
@Override public void deleteInput(@NotNull ConfigurationSection section, int slot) { editInput(section, RecipeMakerGUI.AIR.clone(), slot); }
@Override public void deleteInput(int slot) { editInput(RecipeMakerGUI.AIR.clone(), slot); }
@Override public void deleteOutput(@NotNull ConfigurationSection section, int slot) { }
@Override public void deleteOutput(int slot) { }
@Nullable @Override public ProvidedUIFilter getInput(int slot) { if (slot == 0) { return input; } return null; }

View File

@ -181,7 +181,7 @@ public class RMGRI_Shaped implements RMG_RecipeInterpreter {
}
@Override
public void editInput(@NotNull ConfigurationSection section, @NotNull ProvidedUIFilter input, int slot) {
public void editInput(@NotNull ProvidedUIFilter input, int slot) {
// Just edit bro
setInput(slot, input);
@ -191,7 +191,7 @@ public class RMGRI_Shaped implements RMG_RecipeInterpreter {
}
@Override
public void editOutput(@NotNull ConfigurationSection section, @NotNull ProvidedUIFilter input, int slot) {
public void editOutput(@NotNull ProvidedUIFilter input, int slot) {
// Just edit bro
setOutput(slot, input);
@ -200,9 +200,9 @@ public class RMGRI_Shaped implements RMG_RecipeInterpreter {
section.set(RecipeMakerGUI.OUTPUT_INGREDIENTS, toYML(outputRecipe));
}
@Override public void deleteInput(@NotNull ConfigurationSection section, int slot) { editInput(section, RecipeMakerGUI.AIR.clone(), slot); }
@Override public void deleteInput(int slot) { editInput(RecipeMakerGUI.AIR.clone(), slot); }
@Override public void deleteOutput(@NotNull ConfigurationSection section, int slot) { editOutput(section, RecipeMakerGUI.AIR.clone(), slot); }
@Override public void deleteOutput(int slot) { editOutput(RecipeMakerGUI.AIR.clone(), slot); }
//region Updater, to update old recipes
/**

View File

@ -165,7 +165,7 @@ public class RMGRI_Shapeless implements RMG_RecipeInterpreter {
}
@Override
public void editInput(@NotNull ConfigurationSection section, @NotNull ProvidedUIFilter input, int slot) {
public void editInput(@NotNull ProvidedUIFilter input, int slot) {
// Just edit bro
setInput(slot, input);
@ -175,7 +175,7 @@ public class RMGRI_Shapeless implements RMG_RecipeInterpreter {
}
@Override
public void editOutput(@NotNull ConfigurationSection section, @NotNull ProvidedUIFilter input, int slot) {
public void editOutput(@NotNull ProvidedUIFilter input, int slot) {
// Just edit bro
setOutput(slot, input);
@ -184,7 +184,7 @@ public class RMGRI_Shapeless implements RMG_RecipeInterpreter {
section.set(RecipeMakerGUI.OUTPUT_INGREDIENTS, toYML(outputRecipe));
}
@Override public void deleteInput(@NotNull ConfigurationSection section, int slot) { editInput(section, RecipeMakerGUI.AIR.clone(), slot); }
@Override public void deleteInput(int slot) { editInput(RecipeMakerGUI.AIR.clone(), slot); }
@Override public void deleteOutput(@NotNull ConfigurationSection section, int slot) { editOutput(section, RecipeMakerGUI.AIR.clone(), slot); }
@Override public void deleteOutput(int slot) { editOutput(RecipeMakerGUI.AIR.clone(), slot); }
}

View File

@ -128,7 +128,7 @@ public class RMGRI_Smithing implements RMG_RecipeInterpreter {
}
@Override
public void editInput(@NotNull ConfigurationSection section, @NotNull ProvidedUIFilter input, int slot) {
public void editInput(@NotNull ProvidedUIFilter input, int slot) {
// Just edit bro
setInput(slot, input);
@ -138,7 +138,7 @@ public class RMGRI_Smithing implements RMG_RecipeInterpreter {
}
@Override
public void editOutput(@NotNull ConfigurationSection section, @NotNull ProvidedUIFilter input, int slot) {
public void editOutput(@NotNull ProvidedUIFilter input, int slot) {
// Just edit bro
setOutput(slot, input);
@ -147,9 +147,9 @@ public class RMGRI_Smithing implements RMG_RecipeInterpreter {
section.set(RecipeMakerGUI.OUTPUT_INGREDIENTS, toYML(getOutputItem(), getOutputIngot()));
}
@Override public void deleteInput(@NotNull ConfigurationSection section, int slot) { editInput(section, RecipeMakerGUI.AIR.clone(), slot); }
@Override public void deleteInput(int slot) { editInput(RecipeMakerGUI.AIR.clone(), slot); }
@Override public void deleteOutput(@NotNull ConfigurationSection section, int slot) { editOutput(section, RecipeMakerGUI.AIR.clone(), slot); }
@Override public void deleteOutput(int slot) { editOutput(RecipeMakerGUI.AIR.clone(), slot); }
//region Updater, to update old recipes
/**

View File

@ -0,0 +1,287 @@
package net.Indyuce.mmoitems.gui.edition.recipe.interpreters;
import io.lumine.mythic.lib.api.crafting.uimanager.ProvidedUIFilter;
import io.lumine.mythic.lib.api.util.ui.SilentNumbers;
import net.Indyuce.mmoitems.api.crafting.recipe.Recipe;
import net.Indyuce.mmoitems.gui.edition.recipe.recipes.RecipeMakerGUI;
import org.bukkit.configuration.ConfigurationSection;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
/**
* This class is in charge of converting Shaped Recipes to and fro YML format,
* as well as editing it in a YML configuration and such. <br> <br>
*
* YML Save Format: <br> <code>
*
* - A|B|C|D|E <br>
* - F|G|H|I|J <br>
* - K|L|M|N|O <br>
* - P|Q|R|S|T <br>
* - U|V|W|X|Y
* </code>
*
* @author Gunging
*/
public class RMGRI_SuperShaped implements RMG_RecipeInterpreter {
/**
* Builds a valid 5x5 matrix of input/output recipe.
*
* @param config List as it is saved in the config.
*
* @return Transcribed into array of arrays.
*/
@NotNull ProvidedUIFilter[][] buildIngredientsFromList(@NotNull List<String> config) {
// Start with a base
ProvidedUIFilter[][] ret = new ProvidedUIFilter[5][5];
// Each row ig
for (int r = 0; r < 5; r++) {
// Get current row
String row = config.size() > r ? config.get(r) : null;
//READ//MMOItems.log("\u00a7b*\u00a77 Reading\u00a7b " + row);
// Update it ig
String s = updateRow(row);
//READ//MMOItems.log("\u00a7b*\u00a77 Updated to\u00a7b " + row);
// Split
String[] poofs = s.split("\\|");
// Parse
for (int p = 0; p < 5; p++) {
String poof = poofs.length > p ? poofs[p] : null;
//READ//MMOItems.log("\u00a7b*\u00a77 Coord\u00a7b " + r + " " + p + "\u00a77 as\u00a73 " + poof);
// Parse
ProvidedUIFilter parsed = ProvidedUIFilter.getFromString(poof, null);
if (parsed == null) { parsed = RecipeMakerGUI.AIR.clone(); }
// Add
ret[r][p] = parsed; } }
// And that's your result
return ret;
}
/**
* Turns something like <br> <code>
*
* [ A, B, C, D, E ], <br>
* [ F, G, H, I, J ], <br>
* [ K, L, M, N, O ], <br>
* [ P, Q, R, S, T ], <br>
* [ U, V, W, X, Y ] <br>
*
* </code> <br>
* into <br> <code>
*
* - A|B|C|D|E <br>
* - F|G|H|I|J <br>
* - K|L|M|N|O <br>
* - P|Q|R|S|T <br>
* - U|V|W|X|Y
* </code>
*
* @param ingredients Array of arrays of UIFilters
*
* @return A list of strings to save in a YML Config
*/
@NotNull
ArrayList<String> toYML(@NotNull ProvidedUIFilter[][] ingredients) {
// Well, build it would ye?
ArrayList<String> ret = new ArrayList<>();
for (int r = 0; r < 5; r++) {
// Get row
ProvidedUIFilter[] poofs = ingredients.length > r ? ingredients[r] : new ProvidedUIFilter[5];
// Concatenate
StringBuilder sb = new StringBuilder();
// Build
for (ProvidedUIFilter poof : poofs) {
ProvidedUIFilter providedUIFilter = poof;
if (providedUIFilter == null) { providedUIFilter = RecipeMakerGUI.AIR.clone(); }
// Add bar
if (sb.length() != 0) { sb.append("|"); }
// Add poof
sb.append(providedUIFilter);
}
ret.add(sb.toString());
}
return ret;
}
@NotNull final ProvidedUIFilter[][] inputRecipe;
/**
* Sets the ingredient in the rows matrix.
*
* @param slot The slot, which must be between 0 and 24 (or this method will do nothing)
* @param poof Ingredient to register
*/
public void setInput(int slot, @NotNull ProvidedUIFilter poof) {
if (slot < 0 || slot > 24) { return; }
inputRecipe[SilentNumbers.floor(slot / 5.0)][slot - (5 * SilentNumbers.floor(slot / 5.0))] = poof;
}
@Nullable
@Override public ProvidedUIFilter getInput(int slot) {
if (slot < 0 || slot > 24) { return null; }
return inputRecipe[SilentNumbers.floor(slot / 5.0)][slot - (5 * SilentNumbers.floor(slot / 5.0))];
}
@NotNull final ProvidedUIFilter[][] outputRecipe;
/**
* Sets the ingredient in the rows matrix.
*
* @param slot The slot, which must be between 0 and 24 (or this method will do nothing)
* @param poof Ingredient to register
*/
public void setOutput(int slot, @NotNull ProvidedUIFilter poof) {
if (slot < 0 || slot > 24) { return; }
outputRecipe[SilentNumbers.floor(slot / 5.0)][slot - (5 * SilentNumbers.floor(slot / 5.0))] = poof;
}
@Nullable
@Override public ProvidedUIFilter getOutput(int slot) {
if (slot < 0 || slot > 24) { return null; }
return outputRecipe[SilentNumbers.floor(slot / 5.0)][slot - (5 * SilentNumbers.floor(slot / 5.0))];
}
@NotNull final ConfigurationSection section;
/**
* @return The recipe name section of this recipe. <br>
* <br>
* Basically <b><code>[ID].base.crafting.shaped.[name]</code></b> section
*/
@NotNull public ConfigurationSection getSection() { return section; }
/**
* Generate an interpreter from this <i>updated</i> configuration section.
* <br><br>
* By 'updated' I mean that, for now, we <b>should call {@link RecipeMakerGUI#moveInput()}
* on this configuration before passing it here</b>, to move the input list from being the recipe name
* section itself to the 'input' section within.
*
* @param recipeNameSection <b><code>[ID].base.crafting.shaped.[name]</code></b> section
*/
public RMGRI_SuperShaped(@NotNull ConfigurationSection recipeNameSection) {
// Save
section = recipeNameSection;
// Build Input list
inputRecipe = buildIngredientsFromList(section.getStringList(RecipeMakerGUI.INPUT_INGREDIENTS));
outputRecipe = buildIngredientsFromList(section.getStringList(RecipeMakerGUI.OUTPUT_INGREDIENTS));
}
@Override
public void editInput(@NotNull ProvidedUIFilter input, int slot) {
// Just edit bro
setInput(slot, input);
// Save
section.set(RecipeMakerGUI.INPUT_INGREDIENTS, toYML(inputRecipe));
}
@Override
public void editOutput(@NotNull ProvidedUIFilter input, int slot) {
// Just edit bro
setOutput(slot, input);
// Save
section.set(RecipeMakerGUI.OUTPUT_INGREDIENTS, toYML(outputRecipe));
}
@Override public void deleteInput(int slot) { editInput(RecipeMakerGUI.AIR.clone(), slot); }
@Override public void deleteOutput(int slot) { editOutput(RecipeMakerGUI.AIR.clone(), slot); }
//region Updater, to update old recipes
/**
* No matter what input, the output will always be three Provided UIFilters
* separated by bars, as expected in the current system, filling with AIR
* where necessary.
*
* @param curr Current string
*
* @return A row in correct format
*/
@NotNull public static String updateRow(@Nullable String curr) {
if (curr == null || curr.isEmpty()) { return emptyRow;}
// Bars used? I guess we can check that its written correctly
if (curr.contains("|")) {
// Split by bars
String[] curSplit = curr.split("\\|");
// Correct length?
if (curSplit.length == 5) {
// Assumed to be updated.
return curr;
} else {
// Make sure it is of size three
StringBuilder ret = new StringBuilder();
// Must append three
for (int r = 0; r < 5; r++) {
// Append a bar after the first
if (r != 0) { ret.append("|"); }
// Array has it?
if (r < curSplit.length) { ret.append(RecipeMakerGUI.poofFromLegacy(curSplit[r])); } else { ret.append("v AIR 0"); }
}
// Build and return
return ret.toString();
}
// Not bars, but spaces, might be old format
} else if (curr.contains(" ")) {
// Make string builder
StringBuilder ret = new StringBuilder();
String[] curSplit = curr.split(" ");
// Must append three
for (int r = 0; r < 5; r++) {
// Append a bar after the first
if (r != 0) { ret.append("|"); }
// Array has it?
if (r < curSplit.length) { ret.append(RecipeMakerGUI.poofFromLegacy(curSplit[r])); } else { ret.append("v AIR 0"); }
}
// Build and return
return ret.toString();
// No spaces nor bars, this will just be the first ingredient of the row I guess
} else {
// Just that i guess
return RecipeMakerGUI.poofFromLegacy(curr) + "|v AIR 0|v AIR 0|v AIR 0|v AIR 0";
}
}
public static final String emptyRow = "v AIR 0|v AIR 0|v AIR 0|v AIR 0|v AIR 0";
//endregion
}

View File

@ -17,66 +17,34 @@ public interface RMG_RecipeInterpreter {
/**
* Edits the configuration section's INPUT list.
*
* @param section <b>The 'crafting' section - [ID].base.crafting</b>
* <br><br>
* Note that this is not editing the recipe type nor name itself.
* It is up to the interpreter to create the sections if missing
* or edit them if they are already there.
* <br><br>
* Ex: [ID].base.crafting.shaped.1.input
*
* @param input The user's input, item that will be required
*
* @param slot Slot that the item is going into
*/
void editInput(@NotNull ConfigurationSection section, @NotNull ProvidedUIFilter input, int slot);
void editInput(@NotNull ProvidedUIFilter input, int slot);
/**
* Edits the configuration section's OUTPUT list.
*
* @param section <b>The 'crafting' section - [ID].base.crafting</b>
* <br><br>
* Note that this is not editing the recipe type nor name itself.
* It is up to the interpreter to create the sections if missing
* or edit them if they are already there.
* <br><br>
* Ex: [ID].base.crafting.shaped.1.output
*
* @param input The user's input, item that will be required
*
* @param slot Slot that the item is going into
*/
void editOutput(@NotNull ConfigurationSection section, @NotNull ProvidedUIFilter input, int slot);
void editOutput(@NotNull ProvidedUIFilter input, int slot);
/**
* Edits the configuration section's INPUT list.
*
* @param section <b>The 'crafting' section - [ID].base.crafting</b>
* <br><br>
* Note that this is not editing the recipe type nor name itself.
* It is up to the interpreter to create the sections if missing
* or edit them if they are already there.
* <br><br>
* Ex: [ID].base.crafting.shaped.1.input
*
* @param slot Slot that is getting reset
*/
void deleteInput(@NotNull ConfigurationSection section, int slot);
void deleteInput(int slot);
/**
* Edits the configuration section's OUTPUT list.
*
* @param section <b>The 'crafting' section - [ID].base.crafting</b>
* <br><br>
* Note that this is not editing the recipe type nor name itself.
* It is up to the interpreter to create the sections if missing
* or edit them if they are already there.
* <br><br>
* Ex: [ID].base.crafting.shaped.1.output
*
* @param slot Slot that is getting reset
*/
void deleteOutput(@NotNull ConfigurationSection section, int slot);
void deleteOutput(int slot);
/**
* Fetch the Provided UI Filter in the YML configuration

View File

@ -6,6 +6,7 @@ import io.lumine.mythic.lib.api.util.ui.SilentNumbers;
import io.lumine.mythic.utils.items.ItemFactory;
import io.lumine.mythic.utils.version.ServerVersion;
import net.Indyuce.mmoitems.ItemStats;
import net.Indyuce.mmoitems.MMOItems;
import net.Indyuce.mmoitems.api.edition.StatEdition;
import net.Indyuce.mmoitems.api.util.message.FFPMMOItems;
import net.Indyuce.mmoitems.gui.edition.recipe.recipes.RecipeMakerGUI;
@ -46,7 +47,7 @@ public class RBA_AmountOutput extends RecipeButtonAction {
@NotNull ItemMeta buttonMeta = Objects.requireNonNull(button.getItemMeta());
@NotNull ItemMeta resultMeta = Objects.requireNonNull(resultItem.getItemMeta());
if (ServerVersion.get().getMinor() >= 14 && buttonMeta.hasCustomModelData()) { buttonMeta.setCustomModelData(resultMeta.getCustomModelData()); }
if (ServerVersion.get().getMinor() >= 14 && resultMeta.hasCustomModelData()) { buttonMeta.setCustomModelData(resultMeta.getCustomModelData()); }
if (resultMeta instanceof LeatherArmorMeta) { ((LeatherArmorMeta) buttonMeta).setColor(((LeatherArmorMeta) resultMeta).getColor()); }
if (resultMeta instanceof BannerMeta) { ((BannerMeta) buttonMeta).setPatterns(((BannerMeta) resultMeta).getPatterns()); }
buttonMeta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_DYE, ItemFlag.HIDE_POTION_EFFECTS);

View File

@ -2,7 +2,6 @@ package net.Indyuce.mmoitems.gui.edition.recipe.recipes;
import net.Indyuce.mmoitems.api.item.template.MMOItemTemplate;
import net.Indyuce.mmoitems.gui.edition.recipe.interpreters.RMGRI_BurningLegacy;
import net.Indyuce.mmoitems.gui.edition.recipe.interpreters.RMGRI_Shaped;
import net.Indyuce.mmoitems.gui.edition.recipe.interpreters.RMG_RecipeInterpreter;
import net.Indyuce.mmoitems.gui.edition.recipe.rba.RBA_CookingTime;
import net.Indyuce.mmoitems.gui.edition.recipe.rba.RBA_Experience;

View File

@ -1,6 +1,5 @@
package net.Indyuce.mmoitems.gui.edition.recipe.recipes;
import net.Indyuce.mmoitems.MMOItems;
import net.Indyuce.mmoitems.api.item.template.MMOItemTemplate;
import net.Indyuce.mmoitems.gui.edition.recipe.interpreters.RMGRI_Shaped;
import net.Indyuce.mmoitems.gui.edition.recipe.interpreters.RMG_RecipeInterpreter;
@ -15,11 +14,6 @@ import java.util.HashMap;
/**
* Edits shaped recipes, very nice.
* <br> <br> <code>
* - - - - - - - - - <br>
* 0 1 2 = 0 1 2 - - <br>
* 3 4 5 = 3 4 5 - R <br>
* 6 7 8 = 6 7 8 - - </code>
*
* @author Gunging
*/

View File

@ -0,0 +1,96 @@
package net.Indyuce.mmoitems.gui.edition.recipe.recipes;
import net.Indyuce.mmoitems.api.item.template.MMOItemTemplate;
import net.Indyuce.mmoitems.gui.edition.recipe.interpreters.RMGRI_SuperShaped;
import net.Indyuce.mmoitems.gui.edition.recipe.interpreters.RMG_RecipeInterpreter;
import net.Indyuce.mmoitems.gui.edition.recipe.rba.RBA_HideFromBook;
import net.Indyuce.mmoitems.gui.edition.recipe.rba.RBA_InputOutput;
import net.Indyuce.mmoitems.gui.edition.recipe.registry.RecipeRegistry;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.HashMap;
/**
* Edits super shaped recipes, very nice.
*
* @author Gunging
*/
public class RMG_SuperShaped extends RecipeMakerGUI {
@NotNull HashMap<Integer, Integer> inputLinks = new HashMap<>();
/**
* An editor for a Super Shaped Recipe. Because the recipe is loaded from the YML when this is created,
* concurrent modifications of the same recipe are unsupported.
*
* @param player Player editing the recipe ig
* @param template Template of which a recipe is being edited
* @param recipeName Name of this recipe
*/
public RMG_SuperShaped(@NotNull Player player, @NotNull MMOItemTemplate template, @NotNull String recipeName, @NotNull RecipeRegistry recipeRegistry) {
super(player, template, recipeName, recipeRegistry);
addButton(new RBA_InputOutput(this));
addButton(new RBA_HideFromBook(this));
// Get section and build interpreter
interpreter = new RMGRI_SuperShaped(getNameSection());
// Bind inputs
inputLinks.put(11, 0);
inputLinks.put(12, 1);
inputLinks.put(13, 2);
inputLinks.put(14, 3);
inputLinks.put(15, 4);
inputLinks.put(20, 5);
inputLinks.put(21, 6);
inputLinks.put(22, 7);
inputLinks.put(23, 8);
inputLinks.put(24, 9);
inputLinks.put(29, 10);
inputLinks.put(30, 11);
inputLinks.put(31, 12);
inputLinks.put(32, 13);
inputLinks.put(33, 14);
inputLinks.put(38, 15);
inputLinks.put(39, 16);
inputLinks.put(40, 17);
inputLinks.put(41, 18);
inputLinks.put(42, 19);
inputLinks.put(47, 20);
inputLinks.put(48, 21);
inputLinks.put(49, 22);
inputLinks.put(50, 23);
inputLinks.put(51, 24);
}
@Override public int getButtonsRow() { return 0; }
@Override
public void putRecipe(@NotNull Inventory target) {
// Fill inputs
for (Integer s : inputLinks.keySet()) { target.setItem(s, getDisplay(isShowingInput(), inputLinks.get(s))); }
}
@Override
int getInputSlot(int absolute) {
// Not an input? Not our business
@Nullable Integer found = inputLinks.get(absolute);
// Found or negative
return found != null ? found : -1;
}
@NotNull final RMGRI_SuperShaped interpreter;
@NotNull
@Override
public RMG_RecipeInterpreter getInterpreter() { return interpreter; }
}

View File

@ -415,12 +415,15 @@ public abstract class RecipeMakerGUI extends EditionInventory {
if (isShowingInput()) {
// Delete Input
getInterpreter().deleteInput(getSection(getEditedSection(), "crafting"), ingredient);
getInterpreter().deleteInput(ingredient);
} else {
// Delete Output
getInterpreter().deleteOutput(getSection(getEditedSection(), "crafting"), getInputSlot(event.getRawSlot())); }
getInterpreter().deleteOutput(getInputSlot(event.getRawSlot())); }
// Register
registerTemplateEdition();
// Refresh yes
refreshInventory();

View File

@ -9,7 +9,6 @@ import io.lumine.mythic.lib.api.crafting.recipes.ShapedRecipe;
import io.lumine.mythic.lib.api.crafting.uimanager.ProvidedUIFilter;
import io.lumine.mythic.lib.api.util.Ref;
import io.lumine.mythic.lib.api.util.ui.FriendlyFeedbackProvider;
import net.Indyuce.mmoitems.MMOItems;
import net.Indyuce.mmoitems.api.crafting.MMOItemUIFilter;
import net.Indyuce.mmoitems.api.item.template.MMOItemTemplate;
import net.Indyuce.mmoitems.api.util.message.FFPMMOItems;

View File

@ -0,0 +1,191 @@
package net.Indyuce.mmoitems.gui.edition.recipe.registry;
import io.lumine.mythic.lib.api.crafting.ingredients.ShapedIngredient;
import io.lumine.mythic.lib.api.crafting.outputs.MRORecipe;
import io.lumine.mythic.lib.api.crafting.outputs.MythicRecipeOutput;
import io.lumine.mythic.lib.api.crafting.recipes.MythicRecipeBlueprint;
import io.lumine.mythic.lib.api.crafting.recipes.MythicRecipeStation;
import io.lumine.mythic.lib.api.crafting.recipes.ShapedRecipe;
import io.lumine.mythic.lib.api.crafting.uimanager.ProvidedUIFilter;
import io.lumine.mythic.lib.api.util.Ref;
import io.lumine.mythic.lib.api.util.ui.FriendlyFeedbackProvider;
import net.Indyuce.mmoitems.api.crafting.MMOItemUIFilter;
import net.Indyuce.mmoitems.api.item.template.MMOItemTemplate;
import net.Indyuce.mmoitems.api.util.message.FFPMMOItems;
import net.Indyuce.mmoitems.gui.edition.EditionInventory;
import net.Indyuce.mmoitems.gui.edition.recipe.interpreters.RMGRI_SuperShaped;
import net.Indyuce.mmoitems.gui.edition.recipe.rba.RBA_AmountOutput;
import net.Indyuce.mmoitems.gui.edition.recipe.rba.RBA_HideFromBook;
import net.Indyuce.mmoitems.gui.edition.recipe.recipes.RMG_SuperShaped;
import net.Indyuce.mmoitems.gui.edition.recipe.recipes.RecipeMakerGUI;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
public class RMGRR_SuperShaped implements RecipeRegistry {
@NotNull
@Override public String getRecipeConfigPath() { return "supershaped"; }
@NotNull @Override public String getRecipeTypeName() { return "Super Shaped"; }
@NotNull final ItemStack displayListItem = RecipeMakerGUI.rename(new ItemStack(Material.NOTE_BLOCK), FFPMMOItems.get().getExampleFormat() + "Super Shaped Recipe");
@NotNull @Override public ItemStack getDisplayListItem() { return displayListItem; }
@Override public void openForPlayer(@NotNull EditionInventory inv, @NotNull String recipeName, Object... otherParams) {
new RMG_SuperShaped(inv.getPlayer(), inv.getEdited(), recipeName, this).open(inv.getPreviousPage());
}
@NotNull
@Override
public MythicRecipeBlueprint sendToMythicLib(@NotNull MMOItemTemplate template, @NotNull ConfigurationSection recipeTypeSection, @NotNull String recipeName, @NotNull Ref<NamespacedKey> namespace, @NotNull FriendlyFeedbackProvider ffp) throws IllegalArgumentException {
// Read some values
ConfigurationSection recipeSection = RecipeMakerGUI.moveInput(recipeTypeSection, recipeName);
NamespacedKey nk = namespace.getValue();
if (nk == null) { throw new IllegalArgumentException(FriendlyFeedbackProvider.quickForConsole(FFPMMOItems.get(), "Illegal (Null) Namespace")); }
// Identify the input
ShapedRecipe input = superShapedRecipeFromList(nk.getKey(), new ArrayList<>(recipeSection.getStringList(RecipeMakerGUI.INPUT_INGREDIENTS)), ffp);
if (input == null) { throw new IllegalArgumentException(FriendlyFeedbackProvider.quickForConsole(FFPMMOItems.get(), "Shaped recipe containing only AIR, $fignored$b.")); }
// Read the options and output
ShapedRecipe output = superShapedRecipeFromList(nk.getKey(), new ArrayList<>(recipeSection.getStringList(RecipeMakerGUI.OUTPUT_INGREDIENTS)), ffp);
int outputAmount = recipeSection.getInt(RBA_AmountOutput.AMOUNT_INGREDIENTS, 1);
boolean hideBook = recipeSection.getBoolean(RBA_HideFromBook.BOOK_HIDDEN, false);
// Build Output
ShapedRecipe outputItem = ShapedRecipe.single(nk.getKey(), new ProvidedUIFilter(MMOItemUIFilter.get(), template.getType().getId(), template.getId(), Math.max(outputAmount, 1)));
MythicRecipeOutput outputRecipe = new MRORecipe(outputItem, output);
// That's our blueprint :)
MythicRecipeBlueprint ret = new MythicRecipeBlueprint(input, outputRecipe, nk);
// Enable it
ret.deploy(MythicRecipeStation.WORKBENCH, namespace);
// Hide book if specified
if (hideBook) { namespace.setValue(null); }
// That's it
return ret;
}
/**
* Shorthand for reading list of strings that are intended to be shaped recipes: <br><br>
* <code>
* v AIR 0|v STICK 0|v AIR 0|v STICK 0|v AIR 0 <br>
* v AIR 0|v STICK 0|v AIR 0|v STICK 0|v AIR 0 <br>
* v AIR 0|v STICK 0|v AIR 0|v STICK 0|v AIR 0 <br>
* v AIR 0|v STICK 0|v AIR 0|v STICK 0|v AIR 0 <br>
* v AIR 0|v STICK 0|v AIR 0|v STICK 0|v AIR 0
* </code>
*
* @param namespace Some name to give to this thing, it can be anything really.
*
* @param recipe The list of strings, probably directly from your YML Config
*
* @param ffp Provider of failure text
*
* @return The most optimized version of this recipe, ready to be put into a Blueprint.
* <br> <br>
* Will be <code>null</code> if it would have been only AIR.
*
* @throws IllegalArgumentException If any ingredient is illegal (wrong syntax or something).
*/
@Nullable
public static ShapedRecipe superShapedRecipeFromList(@NotNull String namespace, @NotNull ArrayList<String> recipe, @NotNull FriendlyFeedbackProvider ffp) throws IllegalArgumentException {
// All right lets read them
ArrayList<ShapedIngredient> poofs = new ArrayList<>();
boolean nonAirFound = false;
int rowNumber = 0;
//UPT//MMOItems.log("\u00a7e" + namespace + "\u00a77 loading:");
// Read through the recipe
for (String row : recipe) {
//UPT//MMOItems.log("\u00a7e-\u00a77 " + row);
// Update
String updatedRow = RMGRI_SuperShaped.updateRow(row);
//UPT//MMOItems.log("\u00a7eU-\u00a77 " + updatedRow);
/*
* This row could be in either legacy or new format, and we will assume no combination of them.
*
* Either:
* ANYTHING ANY.THING ANYTHING
*
* or
* A NYT THIN G|A NYT THING|A NYT THIN G
*/
// What are the three ingredients encoded in this row?
String[] positions;
if (updatedRow.contains("|")) {
// Split by |s
positions = updatedRow.split("\\|");
// Is legacy
} else {
// Split by spaces
positions = updatedRow.split(" ");
}
// Size not 3? BRUH
if (positions.length != 5) { throw new IllegalArgumentException("Invalid super crafting table row $u" + updatedRow + "$b ($fNot exactly 5 ingredients wide$b)."); }
// Identify
ProvidedUIFilter left = RecipeMakerGUI.readIngredientFrom(positions[0], ffp);
ProvidedUIFilter midLeft = RecipeMakerGUI.readIngredientFrom(positions[1], ffp);
ProvidedUIFilter center = RecipeMakerGUI.readIngredientFrom(positions[2], ffp);
ProvidedUIFilter midRight = RecipeMakerGUI.readIngredientFrom(positions[3], ffp);
ProvidedUIFilter right = RecipeMakerGUI.readIngredientFrom(positions[4], ffp);
if (!left.isAir()) { nonAirFound = true; }
if (!midLeft.isAir()) { nonAirFound = true; }
if (!center.isAir()) { nonAirFound = true; }
if (!midRight.isAir()) { nonAirFound = true; }
if (!right.isAir()) { nonAirFound = true; }
/*
* To detect if a recipe can be crafted in the survival inventory (and remove extra AIR),
* we must see that a whole row AND a whole column be air. Not any column or row though,
* but any of those that do not cross the center.
*
* If a single left item is not air, LEFT is no longer an unsharped column.
* If a single right item is not air, RIGHT is no longer an unsharped column.
*
* All items must be air in TOP or BOTTOM for they to be unsharped.
*/
// Bake
ShapedIngredient leftIngredient = new ShapedIngredient(left, 0, -rowNumber);
ShapedIngredient midLeftIngredient = new ShapedIngredient(midLeft, 1, -rowNumber);
ShapedIngredient centerIngredient = new ShapedIngredient(center, 2, -rowNumber);
ShapedIngredient midRightIngredient = new ShapedIngredient(midRight, 3, -rowNumber);
ShapedIngredient rightIngredient = new ShapedIngredient(right, 4, -rowNumber);
// Parse and add
poofs.add(leftIngredient);
poofs.add(midLeftIngredient);
poofs.add(centerIngredient);
poofs.add(midRightIngredient);
poofs.add(rightIngredient);
// Prepare for next row
rowNumber++;
}
if (!nonAirFound) { return null; }
// Make ingredients
return ShapedRecipe.unsharpen((new ShapedRecipe(namespace, poofs)));
}
}

View File

@ -169,11 +169,11 @@ public class Crafting extends ItemStat {
// Redirect
if (type == RecipeMakerGUI.INPUT) {
interpreter.editInput(section, read, slot);
interpreter.editInput(read, slot);
// It must be output
} else {
interpreter.editOutput(section, read, slot); }
interpreter.editOutput(read, slot); }
// Save changes
inv.registerTemplateEdition();