mirror of
https://github.com/alexcrea/CustomAnvil.git
synced 2026-06-23 16:16:17 +02:00
Add Custom craft and its config GUI. (#5)
This commit is contained in:
commit
74f36ec899
24 changed files with 1582 additions and 389 deletions
|
|
@ -4,7 +4,7 @@ plugins {
|
|||
}
|
||||
|
||||
group = "xyz.alexcrea"
|
||||
version = "1.3.2-A2"
|
||||
version = "1.4.0a"
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import org.bukkit.configuration.file.FileConfiguration;
|
|||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import xyz.alexcrea.cuanvil.group.EnchantConflictManager;
|
||||
import xyz.alexcrea.cuanvil.group.ItemGroupManager;
|
||||
import xyz.alexcrea.cuanvil.recipe.CustomAnvilRecipeManager;
|
||||
import xyz.alexcrea.cuanvil.util.MetricsUtil;
|
||||
|
||||
import java.io.File;
|
||||
|
|
@ -18,12 +19,14 @@ public abstract class ConfigHolder {
|
|||
public static ItemGroupConfigHolder ITEM_GROUP_HOLDER;
|
||||
public static ConflictConfigHolder CONFLICT_HOLDER;
|
||||
public static UnitRepairHolder UNIT_REPAIR_HOLDER;
|
||||
public static CustomAnvilCraftHolder CUSTOM_RECIPE_HOLDER;
|
||||
|
||||
public static boolean loadConfig() {
|
||||
DEFAULT_CONFIG = new DefaultConfigHolder();
|
||||
ITEM_GROUP_HOLDER = new ItemGroupConfigHolder();
|
||||
CONFLICT_HOLDER = new ConflictConfigHolder();
|
||||
UNIT_REPAIR_HOLDER = new UnitRepairHolder();
|
||||
CUSTOM_RECIPE_HOLDER = new CustomAnvilCraftHolder();
|
||||
|
||||
boolean result = reloadAllFromDisk(true);
|
||||
if (result) {
|
||||
|
|
@ -41,6 +44,9 @@ public abstract class ConfigHolder {
|
|||
sucess = CONFLICT_HOLDER.reloadFromDisk(hardfail);
|
||||
if (!sucess) return false;
|
||||
sucess = UNIT_REPAIR_HOLDER.reloadFromDisk(hardfail);
|
||||
if (!sucess) return false;
|
||||
sucess = CUSTOM_RECIPE_HOLDER.reloadFromDisk(hardfail);
|
||||
|
||||
return sucess;
|
||||
}
|
||||
|
||||
|
|
@ -83,6 +89,7 @@ public abstract class ConfigHolder {
|
|||
|
||||
// Save logic
|
||||
public boolean saveToDisk(boolean doBackup) {
|
||||
CustomAnvil.Companion.log("Saving "+getConfigFileName());
|
||||
if (doBackup) {
|
||||
if (!saveBackup()) {
|
||||
CustomAnvil.instance.getLogger().severe("Could not save backup. see above.");
|
||||
|
|
@ -104,6 +111,7 @@ public abstract class ConfigHolder {
|
|||
return false;
|
||||
}
|
||||
|
||||
CustomAnvil.Companion.log(getConfigFileName()+" saved successfully");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -242,6 +250,7 @@ public abstract class ConfigHolder {
|
|||
public static class UnitRepairHolder extends ResourceConfigHolder {
|
||||
private final static String ITEM_GROUP_FILE_NAME = "unit_repair_item";
|
||||
|
||||
|
||||
private UnitRepairHolder() {
|
||||
super(ITEM_GROUP_FILE_NAME);
|
||||
}
|
||||
|
|
@ -253,4 +262,25 @@ public abstract class ConfigHolder {
|
|||
}
|
||||
|
||||
|
||||
// Class for custom anvil craft
|
||||
public static class CustomAnvilCraftHolder extends ResourceConfigHolder {
|
||||
private final static String CUSTOM_RECIPE_FILE_NAME = "custom_recipes";
|
||||
CustomAnvilRecipeManager recipeManager;
|
||||
|
||||
private CustomAnvilCraftHolder() {
|
||||
super(CUSTOM_RECIPE_FILE_NAME);
|
||||
}
|
||||
|
||||
public CustomAnvilRecipeManager getRecipeManager() {
|
||||
return recipeManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reload() {
|
||||
this.recipeManager = new CustomAnvilRecipeManager();
|
||||
this.recipeManager.prepareRecipes(this.configuration);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
package xyz.alexcrea.cuanvil.gui.config;
|
||||
package xyz.alexcrea.cuanvil.gui.config.global;
|
||||
|
||||
import com.github.stefvanschie.inventoryframework.gui.GuiItem;
|
||||
import com.github.stefvanschie.inventoryframework.pane.Orientable;
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
package xyz.alexcrea.cuanvil.gui.config.global;
|
||||
|
||||
import com.github.stefvanschie.inventoryframework.gui.GuiItem;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.inventory.ItemFlag;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import xyz.alexcrea.cuanvil.config.ConfigHolder;
|
||||
import xyz.alexcrea.cuanvil.gui.config.settings.subsetting.CustomRecipeSubSettingGui;
|
||||
import xyz.alexcrea.cuanvil.recipe.AnvilCustomRecipe;
|
||||
import xyz.alexcrea.cuanvil.util.CasedStringUtil;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class CustomRecipeConfigGui extends MappedElementListConfigGui<AnvilCustomRecipe, CustomRecipeSubSettingGui> {
|
||||
|
||||
|
||||
public final static CustomRecipeConfigGui INSTANCE = new CustomRecipeConfigGui();
|
||||
|
||||
static {
|
||||
INSTANCE.init();
|
||||
}
|
||||
|
||||
private CustomRecipeConfigGui() {
|
||||
super("Custom Recipe Config");
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ItemStack createItemForGeneric(AnvilCustomRecipe recipe) {
|
||||
// Get base item to display
|
||||
ItemStack craftResultItem = recipe.getResultItem();
|
||||
ItemStack displaydItem;
|
||||
if(craftResultItem == null){
|
||||
displaydItem = new ItemStack(Material.BARRIER);
|
||||
}else{
|
||||
displaydItem = craftResultItem.clone();
|
||||
}
|
||||
|
||||
// edit displayed item
|
||||
ItemMeta meta = displaydItem.getItemMeta();
|
||||
|
||||
meta.setDisplayName("\u00A7e" + CasedStringUtil.snakeToUpperSpacedCase(recipe.getName()) + " \u00A7fCustom recipe");
|
||||
meta.addItemFlags(ItemFlag.values());
|
||||
|
||||
boolean shouldWork = recipe.validate();
|
||||
|
||||
meta.setLore(Arrays.asList(
|
||||
"\u00A77Should work: \u00A7"+(shouldWork ? "aYes" : "cNo"),
|
||||
"\u00A77Exact count: \u00A7"+(recipe.getExactCount() ? "aYes" : "cNo"),
|
||||
"\u00A77Recipe Xp Cost: \u00A7e"+recipe.getXpCostPerCraft()
|
||||
|
||||
));
|
||||
|
||||
displaydItem.setItemMeta(meta);
|
||||
return displaydItem;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CustomRecipeSubSettingGui newInstanceOfGui(AnvilCustomRecipe generic, GuiItem item) {
|
||||
return new CustomRecipeSubSettingGui(this, generic, item);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String genericDisplayedName() {
|
||||
return "custom recipe";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AnvilCustomRecipe createAndSaveNewEmptyGeneric(String name) {
|
||||
// Create new empty conflict and display it to the admin
|
||||
AnvilCustomRecipe recipe = new AnvilCustomRecipe(
|
||||
name,
|
||||
AnvilCustomRecipe.Companion.getDEFAULT_EXACT_COUNT_CONFIG(),
|
||||
AnvilCustomRecipe.Companion.getDEFAULT_XP_COST_CONFIG(),
|
||||
AnvilCustomRecipe.Companion.getDEFAULT_LEFT_ITEM_CONFIG(),
|
||||
AnvilCustomRecipe.Companion.getDEFAULT_RIGHT_ITEM_CONFIG(),
|
||||
AnvilCustomRecipe.Companion.getDEFAULT_RESULT_ITEM_CONFIG());
|
||||
|
||||
ConfigHolder.CUSTOM_RECIPE_HOLDER.getRecipeManager().cleanAddNew(recipe);
|
||||
|
||||
// Save recipe to file
|
||||
recipe.saveToFile();
|
||||
|
||||
return recipe;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected List<AnvilCustomRecipe> getEveryDisplayableInstanceOfGeneric() {
|
||||
return ConfigHolder.CUSTOM_RECIPE_HOLDER.getRecipeManager().getRecipeList();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,299 @@
|
|||
package xyz.alexcrea.cuanvil.gui.config.global;
|
||||
|
||||
import com.github.stefvanschie.inventoryframework.gui.GuiItem;
|
||||
import com.github.stefvanschie.inventoryframework.pane.Orientable;
|
||||
import com.github.stefvanschie.inventoryframework.pane.OutlinePane;
|
||||
import com.github.stefvanschie.inventoryframework.pane.Pane;
|
||||
import com.github.stefvanschie.inventoryframework.pane.PatternPane;
|
||||
import com.github.stefvanschie.inventoryframework.pane.util.Pattern;
|
||||
import io.delilaheve.CustomAnvil;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui;
|
||||
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems;
|
||||
import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public abstract class ElementListGlobalConfigGui< T > extends ValueUpdatableGui {
|
||||
|
||||
private final String namePrefix;
|
||||
|
||||
public ElementListGlobalConfigGui(@NotNull String title) {
|
||||
super(6, title, CustomAnvil.instance);
|
||||
this.namePrefix = title;
|
||||
}
|
||||
|
||||
|
||||
protected OutlinePane firstPage;
|
||||
protected ArrayList<OutlinePane> pages;
|
||||
protected HashMap<UUID, Integer> pageMap;
|
||||
protected PatternPane backgroundPane;
|
||||
|
||||
public void init() {
|
||||
// Back item panel
|
||||
Pattern pattern = new Pattern(
|
||||
GuiSharedConstant.EMPTY_GUI_FULL_LINE,
|
||||
GuiSharedConstant.EMPTY_GUI_FULL_LINE,
|
||||
GuiSharedConstant.EMPTY_GUI_FULL_LINE,
|
||||
GuiSharedConstant.EMPTY_GUI_FULL_LINE,
|
||||
GuiSharedConstant.EMPTY_GUI_FULL_LINE,
|
||||
"B11L1R11C"
|
||||
);
|
||||
this.backgroundPane = new PatternPane(0, 0, 9, 6, Pane.Priority.LOW, pattern);
|
||||
|
||||
GuiGlobalItems.addBackItem(this.backgroundPane, MainConfigGui.INSTANCE);
|
||||
|
||||
GuiGlobalItems.addBackgroundItem(this.backgroundPane);
|
||||
this.backgroundPane.bindItem('1', GuiSharedConstant.SECONDARY_BACKGROUND_ITEM);
|
||||
addPane(this.backgroundPane);
|
||||
|
||||
// Page init
|
||||
this.pages = new ArrayList<>();
|
||||
this.pageMap = new HashMap<>();
|
||||
|
||||
// enchant item panel
|
||||
this.firstPage = createEmptyPage();
|
||||
this.pages.add(this.firstPage);
|
||||
|
||||
prepareStaticValues();
|
||||
reloadValues();
|
||||
}
|
||||
|
||||
protected GuiItem goLeftItem;
|
||||
protected GuiItem goRightItem;
|
||||
|
||||
protected void prepareStaticValues(){
|
||||
// Left item creation for consumer & bind
|
||||
this.goLeftItem = new GuiItem(new ItemStack(Material.RED_TERRACOTTA), event -> {
|
||||
HumanEntity viewer = event.getWhoClicked();
|
||||
UUID playerUUID = viewer.getUniqueId();
|
||||
int page = this.pageMap.getOrDefault(playerUUID, 0);
|
||||
this.pageMap.put(playerUUID, page - 1);
|
||||
|
||||
ItemStack cursor = viewer.getItemOnCursor();
|
||||
viewer.setItemOnCursor(new ItemStack(Material.AIR));
|
||||
|
||||
show(viewer);
|
||||
|
||||
viewer.setItemOnCursor(cursor);
|
||||
}, CustomAnvil.instance);
|
||||
|
||||
// Right item creation for consumer & bind
|
||||
this.goRightItem = new GuiItem(new ItemStack(Material.GREEN_TERRACOTTA), event -> {
|
||||
HumanEntity viewer = event.getWhoClicked();
|
||||
UUID playerUUID = viewer.getUniqueId();
|
||||
int page = pageMap.getOrDefault(playerUUID, 0);
|
||||
this.pageMap.put(playerUUID, page + 1);
|
||||
|
||||
ItemStack cursor = viewer.getItemOnCursor();
|
||||
viewer.setItemOnCursor(new ItemStack(Material.AIR));
|
||||
|
||||
show(viewer);
|
||||
|
||||
viewer.setItemOnCursor(cursor);
|
||||
}, CustomAnvil.instance);
|
||||
|
||||
this.backgroundPane.bindItem('C', prepareCreateNewItem());
|
||||
}
|
||||
protected void reloadValues(){
|
||||
this.firstPage.clear();
|
||||
this.pages.clear();
|
||||
this.pages.add(this.firstPage);
|
||||
|
||||
for (T conflict : getEveryDisplayableInstanceOfGeneric()) {
|
||||
updateValueForGeneric(conflict, false);
|
||||
}
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
protected abstract GuiItem prepareCreateNewItem();
|
||||
|
||||
protected OutlinePane createEmptyPage() {
|
||||
OutlinePane page = new OutlinePane(0, 0, 9, 5);
|
||||
page.align(OutlinePane.Alignment.BEGIN);
|
||||
page.setOrientation(Orientable.Orientation.HORIZONTAL);
|
||||
|
||||
return page;
|
||||
}
|
||||
|
||||
public int getPlayerPageID(UUID uuid) {
|
||||
int pageId = this.pageMap.getOrDefault(uuid, 0);
|
||||
if (pageId >= this.pages.size()) {
|
||||
pageId = this.pages.size() - 1;
|
||||
}
|
||||
return pageId;
|
||||
}
|
||||
|
||||
protected void addToPage(GuiItem guiItem) {
|
||||
// Get first available page or create one
|
||||
OutlinePane page = this.pages.get(this.pages.size() - 1);
|
||||
if (page.getItems().size() >= 5 * 9) {
|
||||
page = createEmptyPage();
|
||||
this.pages.add(page);
|
||||
}
|
||||
|
||||
page.addItem(guiItem);
|
||||
}
|
||||
|
||||
private void removeFromPage(GuiItem guiItem) {
|
||||
// get item page
|
||||
OutlinePane page = null;
|
||||
int pageID = 0;
|
||||
while (pageID < this.pages.size()) {
|
||||
OutlinePane tempPage = this.pages.get(pageID);
|
||||
if (tempPage.getItems().contains(guiItem)) {
|
||||
page = tempPage;
|
||||
break;
|
||||
}
|
||||
pageID++;
|
||||
}
|
||||
|
||||
if (page == null) {// Why...
|
||||
return;
|
||||
}
|
||||
removeFromPage(page, pageID, guiItem);
|
||||
}
|
||||
|
||||
private void removeFromPage(OutlinePane page, int pageID, GuiItem guiItem) {
|
||||
page.removeItem(guiItem);
|
||||
|
||||
// There is now a slot available, let fill it if possible
|
||||
if (pageID < (this.pages.size() - 1)) {
|
||||
OutlinePane newPage = this.pages.get(pageID + 1);
|
||||
GuiItem nextPageItem = newPage.getItems().get(0);
|
||||
|
||||
removeFromPage(newPage, pageID + 1, nextPageItem);
|
||||
|
||||
OutlinePane thisPage = this.pages.get(pageID);
|
||||
thisPage.addItem(nextPageItem);
|
||||
} else if (pageID > 0 && page.getItems().isEmpty()) {
|
||||
this.pages.remove(pageID);
|
||||
}
|
||||
}
|
||||
|
||||
public void placeArrow(int page, boolean customise) {
|
||||
|
||||
// Place left arrow
|
||||
addPane(this.backgroundPane);
|
||||
if (page > 0) {
|
||||
if (customise) {
|
||||
ItemStack leftItem = this.goLeftItem.getItem();
|
||||
ItemMeta leftMeta = leftItem.getItemMeta();
|
||||
|
||||
leftMeta.setDisplayName("\u00A7eReturn to page " + (page));
|
||||
|
||||
leftItem.setItemMeta(leftMeta);
|
||||
this.goLeftItem.setItem(leftItem);
|
||||
}
|
||||
|
||||
this.backgroundPane.bindItem('L', this.goLeftItem);
|
||||
} else {
|
||||
this.backgroundPane.bindItem('L', GuiSharedConstant.SECONDARY_BACKGROUND_ITEM);
|
||||
}
|
||||
|
||||
// Place right arrow
|
||||
if (page < pages.size() - 1) {
|
||||
if (customise) {
|
||||
ItemStack rightItem = this.goRightItem.getItem();
|
||||
ItemMeta rightMeta = rightItem.getItemMeta();
|
||||
|
||||
rightMeta.setDisplayName("\u00A7eGo to page " + (page + 2));
|
||||
|
||||
rightItem.setItemMeta(rightMeta);
|
||||
this.goRightItem.setItem(rightItem);
|
||||
}
|
||||
|
||||
this.backgroundPane.bindItem('R', this.goRightItem);
|
||||
} else {
|
||||
this.backgroundPane.bindItem('R', GuiSharedConstant.SECONDARY_BACKGROUND_ITEM);
|
||||
}
|
||||
}
|
||||
|
||||
@Override // assume will not be called in multiple thread
|
||||
public void show(@NotNull HumanEntity humanEntity) {
|
||||
int pageID = getPlayerPageID(humanEntity.getUniqueId());
|
||||
OutlinePane page = this.pages.get(pageID);
|
||||
|
||||
getPanes().clear();
|
||||
|
||||
// display the page arrow pane
|
||||
placeArrow(pageID, true);
|
||||
// and add actual page
|
||||
addPane(page);
|
||||
|
||||
// set title
|
||||
StringBuilder title = new StringBuilder(this.namePrefix);
|
||||
int pagesSize = this.pages.size();
|
||||
if(pagesSize > 1){
|
||||
title.append(" (").append(pageID + 1).append('/').append(pagesSize).append(')');
|
||||
}
|
||||
setTitle(title.toString());
|
||||
|
||||
super.show(humanEntity);
|
||||
|
||||
}
|
||||
|
||||
@Override // assume will not be called in multiple thread
|
||||
public void click(@NotNull InventoryClickEvent event) {
|
||||
int pageID = getPlayerPageID(event.getWhoClicked().getUniqueId());
|
||||
OutlinePane page = this.pages.get(pageID);
|
||||
|
||||
getPanes().clear();
|
||||
|
||||
// set the page arrow pane
|
||||
placeArrow(pageID, false);
|
||||
// and add actual page
|
||||
addPane(page);
|
||||
|
||||
super.click(event);
|
||||
}
|
||||
|
||||
// -------------------------
|
||||
// Methods using generic T
|
||||
// -------------------------
|
||||
|
||||
public void updateValueForGeneric(T generic, boolean shouldUpdate) {
|
||||
ItemStack item = createItemForGeneric(generic);
|
||||
|
||||
updateGeneric(generic, item);
|
||||
|
||||
if (shouldUpdate) {
|
||||
update();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void removeGeneric(T generic) {
|
||||
GuiItem item = findGuiItemForRemoval(generic);
|
||||
if(item == null) return;
|
||||
removeFromPage(item);
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
protected abstract GuiItem findGuiItemForRemoval(T generic);
|
||||
|
||||
protected abstract ItemStack createItemForGeneric(T generic);
|
||||
|
||||
protected abstract void updateGeneric(T generic, ItemStack usedItem);
|
||||
|
||||
protected abstract List<T> getEveryDisplayableInstanceOfGeneric();
|
||||
|
||||
@Override
|
||||
public void updateGuiValues() {
|
||||
// Not the optimised way to update this gui
|
||||
// TODO maybe rework ValueUpdatableGui and it's dependency to allow a 1 item reload every time.
|
||||
|
||||
reloadValues();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,34 +1,20 @@
|
|||
package xyz.alexcrea.cuanvil.gui.config.global;
|
||||
|
||||
import com.github.stefvanschie.inventoryframework.gui.GuiItem;
|
||||
import com.github.stefvanschie.inventoryframework.gui.type.ChestGui;
|
||||
import com.github.stefvanschie.inventoryframework.pane.Orientable;
|
||||
import com.github.stefvanschie.inventoryframework.pane.OutlinePane;
|
||||
import com.github.stefvanschie.inventoryframework.pane.Pane;
|
||||
import com.github.stefvanschie.inventoryframework.pane.PatternPane;
|
||||
import com.github.stefvanschie.inventoryframework.pane.util.Pattern;
|
||||
import io.delilaheve.CustomAnvil;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import xyz.alexcrea.cuanvil.config.ConfigHolder;
|
||||
import xyz.alexcrea.cuanvil.group.EnchantConflictGroup;
|
||||
import xyz.alexcrea.cuanvil.group.IncludeGroup;
|
||||
import xyz.alexcrea.cuanvil.gui.config.settings.subsetting.EnchantConflictSubSettingGui;
|
||||
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions;
|
||||
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems;
|
||||
import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant;
|
||||
import xyz.alexcrea.cuanvil.util.CasedStringUtil;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class EnchantConflictGui extends ChestGui {
|
||||
public class EnchantConflictGui extends MappedElementListConfigGui<EnchantConflictGroup, EnchantConflictSubSettingGui> {
|
||||
|
||||
public final static EnchantConflictGui INSTANCE = new EnchantConflictGui();
|
||||
|
||||
|
|
@ -36,194 +22,37 @@ public class EnchantConflictGui extends ChestGui {
|
|||
INSTANCE.init();
|
||||
}
|
||||
|
||||
private final HashMap<EnchantConflictGroup, EnchantConflictSubSettingGui> conflictGuiMap;
|
||||
|
||||
private EnchantConflictGui() {
|
||||
super(6, "Conflict Config", CustomAnvil.instance);
|
||||
this.conflictGuiMap = new HashMap<>();
|
||||
}
|
||||
|
||||
private OutlinePane firstPage;
|
||||
private ArrayList<OutlinePane> pages;
|
||||
private HashMap<UUID, Integer> pageMap;
|
||||
private PatternPane backgroundPane;
|
||||
|
||||
private void init() {
|
||||
// Back item panel
|
||||
Pattern pattern = new Pattern(
|
||||
GuiSharedConstant.EMPTY_GUI_FULL_LINE,
|
||||
GuiSharedConstant.EMPTY_GUI_FULL_LINE,
|
||||
GuiSharedConstant.EMPTY_GUI_FULL_LINE,
|
||||
GuiSharedConstant.EMPTY_GUI_FULL_LINE,
|
||||
GuiSharedConstant.EMPTY_GUI_FULL_LINE,
|
||||
"B11L1R11C"
|
||||
);
|
||||
this.backgroundPane = new PatternPane(0, 0, 9, 6, Pane.Priority.LOW, pattern);
|
||||
|
||||
GuiGlobalItems.addBackItem(this.backgroundPane, MainConfigGui.INSTANCE);
|
||||
|
||||
GuiGlobalItems.addBackgroundItem(this.backgroundPane);
|
||||
this.backgroundPane.bindItem('1', GuiSharedConstant.SECONDARY_BACKGROUND_ITEM);
|
||||
addPane(this.backgroundPane);
|
||||
|
||||
// Page init
|
||||
this.pages = new ArrayList<>();
|
||||
this.pageMap = new HashMap<>();
|
||||
|
||||
// enchant item panel
|
||||
this.firstPage = createEmptyPage();
|
||||
this.pages.add(this.firstPage);
|
||||
|
||||
prepareOtherValues();
|
||||
reloadValues();
|
||||
}
|
||||
|
||||
|
||||
private GuiItem goLeftItem;
|
||||
private GuiItem goRightItem;
|
||||
|
||||
private void prepareOtherValues() {
|
||||
// Left item creation for consumer & bind
|
||||
this.goLeftItem = new GuiItem(new ItemStack(Material.RED_TERRACOTTA), event -> {
|
||||
HumanEntity viewer = event.getWhoClicked();
|
||||
UUID playerUUID = viewer.getUniqueId();
|
||||
int page = this.pageMap.getOrDefault(playerUUID, 0);
|
||||
this.pageMap.put(playerUUID, page - 1);
|
||||
|
||||
ItemStack cursor = viewer.getItemOnCursor();
|
||||
viewer.setItemOnCursor(new ItemStack(Material.AIR));
|
||||
|
||||
show(viewer);
|
||||
|
||||
viewer.setItemOnCursor(cursor);
|
||||
}, CustomAnvil.instance);
|
||||
|
||||
// Right item creation for consumer & bind
|
||||
this.goRightItem = new GuiItem(new ItemStack(Material.GREEN_TERRACOTTA), event -> {
|
||||
HumanEntity viewer = event.getWhoClicked();
|
||||
UUID playerUUID = viewer.getUniqueId();
|
||||
int page = pageMap.getOrDefault(playerUUID, 0);
|
||||
this.pageMap.put(playerUUID, page + 1);
|
||||
|
||||
ItemStack cursor = viewer.getItemOnCursor();
|
||||
viewer.setItemOnCursor(new ItemStack(Material.AIR));
|
||||
|
||||
show(viewer);
|
||||
|
||||
viewer.setItemOnCursor(cursor);
|
||||
}, CustomAnvil.instance);
|
||||
|
||||
// Create new conflict item
|
||||
ItemStack createItem = new ItemStack(Material.PAPER);
|
||||
ItemMeta createMeta = createItem.getItemMeta();
|
||||
|
||||
createMeta.setDisplayName("\u00A7aCreate new conflict");
|
||||
createMeta.setLore(Arrays.asList(
|
||||
"\u00A77Create a new anvil restriction.",
|
||||
"\u00A77You will be asked to name the conflict in chat.",
|
||||
"\u00A77Then, you should edit the conflict config as you need"
|
||||
));
|
||||
|
||||
createItem.setItemMeta(createMeta);
|
||||
|
||||
this.backgroundPane.bindItem('C', new GuiItem(createItem, (clickEvent) -> {
|
||||
clickEvent.setCancelled(true);
|
||||
HumanEntity player = clickEvent.getWhoClicked();
|
||||
|
||||
// check permission
|
||||
if (!player.hasPermission(CustomAnvil.editConfigPermission)) {
|
||||
player.closeInventory();
|
||||
player.sendMessage(GuiGlobalActions.NO_EDIT_PERM);
|
||||
return;
|
||||
}
|
||||
player.closeInventory();
|
||||
|
||||
player.sendMessage("\u00A7eWrite the conflict you want to create in the chat.\n" +
|
||||
"\u00A7eOr write \u00A7ccancel \u00A7eto go back to conflict config menu");
|
||||
|
||||
CustomAnvil.Companion.getChatListener().setListenedCallback(player, prepareCreateItemConsumer(player));
|
||||
|
||||
}, CustomAnvil.instance));
|
||||
}
|
||||
|
||||
private Consumer<String> prepareCreateItemConsumer(HumanEntity player) {
|
||||
AtomicReference<Consumer<String>> selfRef = new AtomicReference<>();
|
||||
Consumer<String> selfCallback = (message) -> {
|
||||
if (message == null) return;
|
||||
|
||||
message = message.toLowerCase(Locale.ROOT);
|
||||
if ("cancel".equalsIgnoreCase(message)) {
|
||||
player.sendMessage("conflict creation cancelled...");
|
||||
show(player);
|
||||
return;
|
||||
}
|
||||
|
||||
message = message.replace(' ', '_');
|
||||
|
||||
// Try to find if it already exists in a for loop
|
||||
// Not the most efficient on large number of conflict, but it should not run often.
|
||||
for (EnchantConflictGroup conflict : ConfigHolder.CONFLICT_HOLDER.getConflictManager().getConflictList()) {
|
||||
if (conflict.getName().equalsIgnoreCase(message)) {
|
||||
player.sendMessage("\u00A7cPlease enter a conflict name that do not already exist...");
|
||||
// wait next message.
|
||||
CustomAnvil.Companion.getChatListener().setListenedCallback(player, selfRef.get());
|
||||
return;
|
||||
}
|
||||
super( "Conflict Config");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected EnchantConflictGroup createAndSaveNewEmptyGeneric(String name){
|
||||
// Create new empty conflict and display it to the admin
|
||||
EnchantConflictGroup conflict = new EnchantConflictGroup(
|
||||
message,
|
||||
name,
|
||||
new IncludeGroup("new_group"),
|
||||
0);
|
||||
|
||||
ConfigHolder.CONFLICT_HOLDER.getConflictManager().getConflictList().add(conflict);
|
||||
updateValueForConflict(conflict, true);
|
||||
|
||||
// save empty conflict in config
|
||||
String[] emptyStringArray = new String[0];
|
||||
|
||||
FileConfiguration config = ConfigHolder.CONFLICT_HOLDER.getConfig();
|
||||
config.set(message + ".enchantments", emptyStringArray);
|
||||
config.set(message + ".notAffectedGroups", emptyStringArray);
|
||||
config.set(message + ".maxEnchantmentBeforeConflict", 0);
|
||||
config.set(name + ".enchantments", emptyStringArray);
|
||||
config.set(name + ".notAffectedGroups", emptyStringArray);
|
||||
config.set(name + ".maxEnchantmentBeforeConflict", 0);
|
||||
|
||||
if (GuiSharedConstant.TEMPORARY_DO_SAVE_TO_DISK_EVERY_CHANGE) {
|
||||
ConfigHolder.CONFLICT_HOLDER.saveToDisk(GuiSharedConstant.TEMPORARY_DO_BACKUP_EVERY_SAVE);
|
||||
}
|
||||
|
||||
// show the new conflict config to the player
|
||||
this.conflictGuiMap.get(conflict).show(player);
|
||||
|
||||
};
|
||||
|
||||
selfRef.set(selfCallback);
|
||||
return selfCallback;
|
||||
return conflict;
|
||||
}
|
||||
|
||||
private OutlinePane createEmptyPage() {
|
||||
OutlinePane page = new OutlinePane(0, 0, 9, 5);
|
||||
page.align(OutlinePane.Alignment.BEGIN);
|
||||
page.setOrientation(Orientable.Orientation.HORIZONTAL);
|
||||
|
||||
return page;
|
||||
}
|
||||
|
||||
public void reloadValues() {
|
||||
this.conflictGuiMap.forEach((conflict, gui) -> gui.cleanUnused());
|
||||
this.conflictGuiMap.clear();
|
||||
this.firstPage.clear();
|
||||
this.pages.clear();
|
||||
this.pages.add(this.firstPage);
|
||||
|
||||
for (EnchantConflictGroup conflict : ConfigHolder.CONFLICT_HOLDER.getConflictManager().getConflictList()) {
|
||||
updateValueForConflict(conflict, false);
|
||||
}
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
public static ItemStack createItemForConflict(EnchantConflictGroup conflict) {
|
||||
@Override
|
||||
public ItemStack createItemForGeneric(EnchantConflictGroup conflict) {
|
||||
ItemStack item = new ItemStack(conflict.getRepresentativeMaterial());
|
||||
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
|
|
@ -239,169 +68,19 @@ public class EnchantConflictGui extends ChestGui {
|
|||
return item;
|
||||
}
|
||||
|
||||
public void updateValueForConflict(EnchantConflictGroup conflict, boolean shouldUpdate) {
|
||||
EnchantConflictSubSettingGui gui = this.conflictGuiMap.get(conflict);
|
||||
ItemStack item = createItemForConflict(conflict);
|
||||
|
||||
GuiItem guiItem;
|
||||
if (gui == null) {
|
||||
// Create new sub setting gui
|
||||
guiItem = new GuiItem(item, CustomAnvil.instance);
|
||||
gui = new EnchantConflictSubSettingGui(this, conflict, guiItem);
|
||||
|
||||
guiItem.setAction(GuiGlobalActions.openGuiAction(gui));
|
||||
|
||||
this.conflictGuiMap.put(conflict, gui);
|
||||
addToPage(guiItem);
|
||||
} else {
|
||||
// Replace item with the updated one
|
||||
guiItem = gui.getParentItemForThisGui();
|
||||
guiItem.setItem(item);
|
||||
@Override
|
||||
protected EnchantConflictSubSettingGui newInstanceOfGui(EnchantConflictGroup conflict, GuiItem item) {
|
||||
return new EnchantConflictSubSettingGui(this, conflict, item);
|
||||
}
|
||||
|
||||
gui.updateLocal();
|
||||
if (shouldUpdate) {
|
||||
update();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void removeConflict(EnchantConflictGroup conflict) {
|
||||
EnchantConflictSubSettingGui gui = this.conflictGuiMap.get(conflict);
|
||||
if (gui == null) return;
|
||||
|
||||
this.conflictGuiMap.remove(conflict);
|
||||
removeFromPage(gui.getParentItemForThisGui());
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
private void addToPage(GuiItem guiItem) {
|
||||
// Get first available page or create one
|
||||
OutlinePane page = this.pages.get(this.pages.size() - 1);
|
||||
if (page.getItems().size() >= 5 * 9) {
|
||||
page = createEmptyPage();
|
||||
this.pages.add(page);
|
||||
}
|
||||
|
||||
page.addItem(guiItem);
|
||||
}
|
||||
|
||||
private void removeFromPage(GuiItem guiItem) {
|
||||
// get item page
|
||||
OutlinePane page = null;
|
||||
int pageID = 0;
|
||||
while (pageID < this.pages.size()) {
|
||||
OutlinePane tempPage = this.pages.get(pageID);
|
||||
if (tempPage.getItems().contains(guiItem)) {
|
||||
page = tempPage;
|
||||
break;
|
||||
}
|
||||
pageID++;
|
||||
}
|
||||
|
||||
if (page == null) {// Why...
|
||||
return;
|
||||
}
|
||||
removeFromPage(page, pageID, guiItem);
|
||||
}
|
||||
|
||||
private void removeFromPage(OutlinePane page, int pageID, GuiItem guiItem) {
|
||||
page.removeItem(guiItem);
|
||||
|
||||
// There is now a slot available, let fill it if possible
|
||||
if (pageID < (this.pages.size() - 1)) {
|
||||
OutlinePane newPage = this.pages.get(pageID + 1);
|
||||
GuiItem nextPageItem = newPage.getItems().get(0);
|
||||
|
||||
removeFromPage(newPage, pageID + 1, nextPageItem);
|
||||
|
||||
OutlinePane thisPage = this.pages.get(pageID);
|
||||
thisPage.addItem(nextPageItem);
|
||||
} else if (pageID > 0 && page.getItems().isEmpty()) {
|
||||
this.pages.remove(pageID);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public int getPlayerPageID(UUID uuid) {
|
||||
int pageId = this.pageMap.getOrDefault(uuid, 0);
|
||||
if (pageId >= this.pages.size()) {
|
||||
pageId = this.pages.size() - 1;
|
||||
}
|
||||
return pageId;
|
||||
}
|
||||
|
||||
public void placeArrow(int page, boolean customise) {
|
||||
|
||||
// Place left arrow
|
||||
addPane(this.backgroundPane);
|
||||
if (page > 0) {
|
||||
if (customise) {
|
||||
ItemStack leftItem = this.goLeftItem.getItem();
|
||||
ItemMeta leftMeta = leftItem.getItemMeta();
|
||||
|
||||
leftMeta.setDisplayName("\u00A7eReturn to page " + (page));
|
||||
|
||||
leftItem.setItemMeta(leftMeta);
|
||||
this.goLeftItem.setItem(leftItem);
|
||||
}
|
||||
|
||||
this.backgroundPane.bindItem('L', this.goLeftItem);
|
||||
} else {
|
||||
this.backgroundPane.bindItem('L', GuiSharedConstant.SECONDARY_BACKGROUND_ITEM);
|
||||
}
|
||||
|
||||
// Place right arrow
|
||||
if (page < pages.size() - 1) {
|
||||
if (customise) {
|
||||
ItemStack rightItem = this.goRightItem.getItem();
|
||||
ItemMeta rightMeta = rightItem.getItemMeta();
|
||||
|
||||
rightMeta.setDisplayName("\u00A7eGo to page " + (page + 2));
|
||||
|
||||
rightItem.setItemMeta(rightMeta);
|
||||
this.goRightItem.setItem(rightItem);
|
||||
}
|
||||
|
||||
this.backgroundPane.bindItem('R', this.goRightItem);
|
||||
} else {
|
||||
this.backgroundPane.bindItem('R', GuiSharedConstant.SECONDARY_BACKGROUND_ITEM);
|
||||
}
|
||||
}
|
||||
|
||||
@Override // assume will not be called in multiple thread
|
||||
public void show(@NotNull HumanEntity humanEntity) {
|
||||
int pageID = getPlayerPageID(humanEntity.getUniqueId());
|
||||
OutlinePane page = this.pages.get(pageID);
|
||||
|
||||
getPanes().clear();
|
||||
|
||||
// display the page arrow pane
|
||||
placeArrow(pageID, true);
|
||||
// and add actual page
|
||||
addPane(page);
|
||||
|
||||
// set title
|
||||
setTitle("Conflict Config (" + (pageID + 1) + "/" + (pages.size()) + ")");
|
||||
|
||||
super.show(humanEntity);
|
||||
|
||||
}
|
||||
|
||||
@Override // assume will not be called in multiple thread
|
||||
public void click(@NotNull InventoryClickEvent event) {
|
||||
int pageID = getPlayerPageID(event.getWhoClicked().getUniqueId());
|
||||
OutlinePane page = this.pages.get(pageID);
|
||||
|
||||
getPanes().clear();
|
||||
|
||||
// set the page arrow pane
|
||||
placeArrow(pageID, false);
|
||||
// and add actual page
|
||||
addPane(page);
|
||||
|
||||
super.click(event);
|
||||
@Override
|
||||
protected String genericDisplayedName() {
|
||||
return "conflict";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<EnchantConflictGroup> getEveryDisplayableInstanceOfGeneric() {
|
||||
return ConfigHolder.CONFLICT_HOLDER.getConflictManager().getConflictList();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ import org.bukkit.inventory.meta.ItemMeta;
|
|||
import xyz.alexcrea.cuanvil.config.ConfigHolder;
|
||||
import xyz.alexcrea.cuanvil.enchant.EnchantmentProperties;
|
||||
import xyz.alexcrea.cuanvil.enchant.EnchantmentRarity;
|
||||
import xyz.alexcrea.cuanvil.gui.config.AbstractEnchantConfigGui;
|
||||
import xyz.alexcrea.cuanvil.gui.config.settings.EnchantCostSettingsGui;
|
||||
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems;
|
||||
import xyz.alexcrea.cuanvil.util.CasedStringUtil;
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ import com.github.stefvanschie.inventoryframework.gui.GuiItem;
|
|||
import org.bukkit.Material;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import xyz.alexcrea.cuanvil.config.ConfigHolder;
|
||||
import xyz.alexcrea.cuanvil.gui.config.AbstractEnchantConfigGui;
|
||||
import xyz.alexcrea.cuanvil.gui.config.settings.IntSettingsGui;
|
||||
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems;
|
||||
import xyz.alexcrea.cuanvil.util.CasedStringUtil;
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ public class MainConfigGui extends ChestGui {
|
|||
private void init() {
|
||||
Pattern pattern = new Pattern(
|
||||
"I00000000",
|
||||
"012304560",
|
||||
"012304567",
|
||||
"Q00000000"
|
||||
);
|
||||
PatternPane pane = new PatternPane(0, 0, 9, 3, pattern);
|
||||
|
|
@ -70,7 +70,7 @@ public class MainConfigGui extends ChestGui {
|
|||
GuiItem enchantCostItem = GuiGlobalItems.goToGuiItem(enchantCostItemstack, EnchantCostConfigGui.INSTANCE);
|
||||
pane.bindItem('3', enchantCostItem);
|
||||
|
||||
// Enchantment Conflicts
|
||||
// Enchantment Conflicts item
|
||||
ItemStack EnchantConflictItemstack = new ItemStack(Material.OAK_FENCE);
|
||||
ItemMeta enchantConflictMeta = EnchantConflictItemstack.getItemMeta();
|
||||
|
||||
|
|
@ -93,6 +93,17 @@ public class MainConfigGui extends ChestGui {
|
|||
pane.bindItem('5', wip5);
|
||||
pane.bindItem('6', wip6);
|
||||
|
||||
// Custom recipe item
|
||||
ItemStack customRecipeItemstack = new ItemStack(Material.CRAFTING_TABLE);
|
||||
ItemMeta customRecipeMeta = EnchantConflictItemstack.getItemMeta();
|
||||
|
||||
customRecipeMeta.setDisplayName("\u00A7aCustom recipes");
|
||||
customRecipeMeta.setLore(Collections.singletonList("\u00A77Click here to open anvil custom recipe menu"));
|
||||
customRecipeItemstack.setItemMeta(customRecipeMeta);
|
||||
|
||||
GuiItem customRecipeItem = GuiGlobalItems.goToGuiItem(customRecipeItemstack, CustomRecipeConfigGui.INSTANCE);
|
||||
pane.bindItem('7', customRecipeItem);
|
||||
|
||||
// quit item
|
||||
ItemStack quitItemstack = new ItemStack(Material.BARRIER);
|
||||
ItemMeta quitMeta = quitItemstack.getItemMeta();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,156 @@
|
|||
package xyz.alexcrea.cuanvil.gui.config.global;
|
||||
|
||||
import com.github.stefvanschie.inventoryframework.gui.GuiItem;
|
||||
import io.delilaheve.CustomAnvil;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import xyz.alexcrea.cuanvil.gui.config.settings.subsetting.MappedToListSubSettingGui;
|
||||
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions;
|
||||
import xyz.alexcrea.cuanvil.interfaces.Named;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public abstract class MappedElementListConfigGui< T extends Named, S extends MappedToListSubSettingGui> extends ElementListGlobalConfigGui< T > {
|
||||
|
||||
|
||||
protected final HashMap<T, S> elementGuiMap;
|
||||
public MappedElementListConfigGui(@NotNull String title) {
|
||||
super(title);
|
||||
this.elementGuiMap = new HashMap<>();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected GuiItem prepareCreateNewItem(){
|
||||
// Create new conflict item
|
||||
ItemStack createItem = new ItemStack(Material.PAPER);
|
||||
ItemMeta createMeta = createItem.getItemMeta();
|
||||
|
||||
createMeta.setDisplayName("\u00A7aCreate new "+genericDisplayedName());
|
||||
createMeta.setLore(Arrays.asList(
|
||||
"\u00A77Create a new "+genericDisplayedName()+".",
|
||||
"\u00A77You will be asked to name the "+genericDisplayedName()+" in chat.",
|
||||
"\u00A77Then, you should edit the "+genericDisplayedName()+" config as you need"
|
||||
));
|
||||
|
||||
createItem.setItemMeta(createMeta);
|
||||
|
||||
return new GuiItem(createItem, (clickEvent) -> {
|
||||
clickEvent.setCancelled(true);
|
||||
HumanEntity player = clickEvent.getWhoClicked();
|
||||
|
||||
// check permission
|
||||
if (!player.hasPermission(CustomAnvil.editConfigPermission)) {
|
||||
player.closeInventory();
|
||||
player.sendMessage(GuiGlobalActions.NO_EDIT_PERM);
|
||||
return;
|
||||
}
|
||||
player.closeInventory();
|
||||
|
||||
player.sendMessage("\u00A7eWrite the "+genericDisplayedName()+" name you want to create in the chat.\n" +
|
||||
"\u00A7eOr write \u00A7ccancel \u00A7eto go back to "+genericDisplayedName()+" config menu");
|
||||
|
||||
CustomAnvil.Companion.getChatListener().setListenedCallback(player, prepareCreateItemConsumer(player));
|
||||
|
||||
}, CustomAnvil.instance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reloadValues() {
|
||||
this.elementGuiMap.forEach((conflict, gui) -> gui.cleanUnused());
|
||||
this.elementGuiMap.clear();
|
||||
|
||||
super.reloadValues();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateGeneric(T generic, ItemStack usedItem) {
|
||||
S gui = this.elementGuiMap.get(generic);
|
||||
|
||||
GuiItem guiItem;
|
||||
if (gui == null) {
|
||||
// Create new sub setting gui
|
||||
guiItem = new GuiItem(usedItem, CustomAnvil.instance);
|
||||
gui = newInstanceOfGui(generic, guiItem);
|
||||
|
||||
guiItem.setAction(GuiGlobalActions.openGuiAction(gui));
|
||||
|
||||
this.elementGuiMap.put(generic, gui);
|
||||
addToPage(guiItem);
|
||||
} else {
|
||||
// Replace item with the updated one
|
||||
guiItem = gui.getParentItemForThisGui();
|
||||
guiItem.setItem(usedItem);
|
||||
}
|
||||
gui.updateLocal();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected GuiItem findGuiItemForRemoval(T generic) {
|
||||
S gui = this.elementGuiMap.get(generic);
|
||||
if (gui == null) return null;
|
||||
|
||||
this.elementGuiMap.remove(generic);
|
||||
return gui.getParentItemForThisGui();
|
||||
}
|
||||
|
||||
protected Consumer<String> prepareCreateItemConsumer(HumanEntity player){
|
||||
AtomicReference<Consumer<String>> selfRef = new AtomicReference<>();
|
||||
Consumer<String> selfCallback = (message) -> {
|
||||
if (message == null) return;
|
||||
|
||||
// check permission
|
||||
if (!player.hasPermission(CustomAnvil.editConfigPermission)) {
|
||||
player.sendMessage(GuiGlobalActions.NO_EDIT_PERM);
|
||||
return;
|
||||
}
|
||||
|
||||
message = message.toLowerCase(Locale.ROOT);
|
||||
if ("cancel".equalsIgnoreCase(message)) {
|
||||
player.sendMessage(genericDisplayedName()+" creation cancelled...");
|
||||
show(player);
|
||||
return;
|
||||
}
|
||||
|
||||
message = message.replace(' ', '_');
|
||||
|
||||
// Try to find if it already exists in a for loop
|
||||
// Not the most efficient on large number of conflict, but it should not run often.
|
||||
for (T generic : getEveryDisplayableInstanceOfGeneric()) {
|
||||
if (generic.getName().equalsIgnoreCase(message)) {
|
||||
player.sendMessage("\u00A7cPlease enter a "+genericDisplayedName()+" name that do not already exist...");
|
||||
// wait next message.
|
||||
CustomAnvil.Companion.getChatListener().setListenedCallback(player, selfRef.get());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
T generic = createAndSaveNewEmptyGeneric(message);
|
||||
|
||||
updateValueForGeneric(generic, true);
|
||||
|
||||
// show the new conflict config to the player
|
||||
this.elementGuiMap.get(generic).show(player);
|
||||
|
||||
update();
|
||||
};
|
||||
|
||||
selfRef.set(selfCallback);
|
||||
return selfCallback;
|
||||
}
|
||||
|
||||
protected abstract S newInstanceOfGui(T generic, GuiItem item);
|
||||
|
||||
protected abstract String genericDisplayedName();
|
||||
|
||||
protected abstract T createAndSaveNewEmptyGeneric(String name);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,254 @@
|
|||
package xyz.alexcrea.cuanvil.gui.config.settings;
|
||||
|
||||
import com.github.stefvanschie.inventoryframework.gui.GuiItem;
|
||||
import com.github.stefvanschie.inventoryframework.pane.PatternPane;
|
||||
import com.github.stefvanschie.inventoryframework.pane.util.Pattern;
|
||||
import io.delilaheve.CustomAnvil;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import xyz.alexcrea.cuanvil.config.ConfigHolder;
|
||||
import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui;
|
||||
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems;
|
||||
import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant;
|
||||
import xyz.alexcrea.cuanvil.util.MetricsUtil;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* An instance of a gui used to edit an item setting.
|
||||
*/
|
||||
public class ItemSettingGui extends AbstractSettingGui {
|
||||
|
||||
private final ItemSettingFactory holder;
|
||||
private final ItemStack before;
|
||||
private ItemStack now;
|
||||
|
||||
/**
|
||||
* Create an item setting config gui.
|
||||
*
|
||||
* @param holder Configuration factory of this setting.
|
||||
* @param now The defined value of this setting.
|
||||
*/
|
||||
protected ItemSettingGui(ItemSettingFactory holder, ItemStack now) {
|
||||
super(3, holder.getTitle(), holder.parent);
|
||||
this.holder = holder;
|
||||
this.before = now;
|
||||
this.now = now;
|
||||
|
||||
prepareStaticItems();
|
||||
updateValueDisplay();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pattern getGuiPattern() {
|
||||
return new Pattern(
|
||||
GuiSharedConstant.EMPTY_GUI_FULL_LINE,
|
||||
"D0-0v0+0s",
|
||||
"B0000000S"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
public void prepareStaticItems(){
|
||||
prepareReturnToDefault();
|
||||
|
||||
ItemStack item = new ItemStack(Material.YELLOW_TERRACOTTA);
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
|
||||
meta.setDisplayName("\u00A7eTemporary close this menu");
|
||||
meta.setLore(Collections.singletonList("\u00A77Allow you to chose other item then return here."));
|
||||
item.setItemMeta(meta);
|
||||
GuiItem guiItem = new GuiItem(item, event -> {
|
||||
event.setCancelled(true);
|
||||
|
||||
HumanEntity player = event.getWhoClicked();
|
||||
|
||||
CustomAnvil.Companion.getChatListener().setListenedCallback(player, (message) ->{
|
||||
|
||||
if(message == null) return;
|
||||
show(player);
|
||||
|
||||
});
|
||||
|
||||
player.sendMessage("\u00A7eWrite something in chat to return to the item config menu.");
|
||||
player.closeInventory();
|
||||
}, CustomAnvil.instance);
|
||||
|
||||
getPane().bindItem('s', guiItem);
|
||||
}
|
||||
|
||||
|
||||
protected GuiItem returnToDefault;
|
||||
|
||||
/**
|
||||
* Prepare "return to default value" gui item.
|
||||
*/
|
||||
protected void prepareReturnToDefault() {
|
||||
ItemStack item = new ItemStack(Material.COMMAND_BLOCK);
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
|
||||
meta.setDisplayName("\u00A7eReset to default value");
|
||||
meta.setLore(Collections.singletonList("\u00A77Default value is: " + holder.defaultVal));
|
||||
item.setItemMeta(meta);
|
||||
returnToDefault = new GuiItem(item, event -> {
|
||||
event.setCancelled(true);
|
||||
now = holder.defaultVal;
|
||||
updateValueDisplay();
|
||||
update();
|
||||
}, CustomAnvil.instance);
|
||||
}
|
||||
|
||||
protected final static List<String> CLICK_LORE = Collections.singletonList("\u00A77Click Here with an item to change the value");
|
||||
|
||||
/**
|
||||
* Update item using the setting value to match the new value
|
||||
*/
|
||||
protected void updateValueDisplay() {
|
||||
PatternPane pane = getPane();
|
||||
|
||||
// Get displayed value for this config.
|
||||
ItemStack displayedItem;
|
||||
if(this.now != null){
|
||||
displayedItem = this.now.clone();
|
||||
}else{
|
||||
displayedItem = new ItemStack(Material.BARRIER);
|
||||
ItemMeta valueMeta = displayedItem.getItemMeta();
|
||||
|
||||
valueMeta.setDisplayName("\u00A74NO ITEM SET");
|
||||
valueMeta.setLore(CLICK_LORE);
|
||||
|
||||
displayedItem.setItemMeta(valueMeta);
|
||||
}
|
||||
|
||||
GuiItem resultItem = new GuiItem(displayedItem, setItemAsCursor(), CustomAnvil.instance);
|
||||
pane.bindItem('v', resultItem);
|
||||
|
||||
// reset to default
|
||||
GuiItem returnToDefault;
|
||||
if (now != holder.defaultVal) {
|
||||
returnToDefault = this.returnToDefault;
|
||||
} else {
|
||||
returnToDefault = GuiGlobalItems.backgroundItem();
|
||||
}
|
||||
pane.bindItem('D', returnToDefault);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return A consumer to update the current setting's value.
|
||||
*/
|
||||
protected Consumer<InventoryClickEvent> setItemAsCursor() { //TODO redo consumer
|
||||
return event -> {
|
||||
event.setCancelled(true);
|
||||
|
||||
HumanEntity player = event.getWhoClicked();
|
||||
ItemStack cursor = player.getItemOnCursor();
|
||||
|
||||
if(cursor.getType().isAir()) return;
|
||||
|
||||
this.now = cursor;
|
||||
|
||||
updateValueDisplay();
|
||||
update();
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onSave() {
|
||||
holder.config.getConfig().set(holder.configPath, this.now);
|
||||
|
||||
MetricsUtil.INSTANCE.notifyChange(this.holder.config, this.holder.configPath);
|
||||
if (GuiSharedConstant.TEMPORARY_DO_SAVE_TO_DISK_EVERY_CHANGE) {
|
||||
return holder.config.saveToDisk(GuiSharedConstant.TEMPORARY_DO_BACKUP_EVERY_SAVE);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hadChange() {
|
||||
if(now == null) {
|
||||
return before != null;
|
||||
}
|
||||
|
||||
return !now.equals(before);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create aa item setting factory from setting's parameters.
|
||||
*
|
||||
* @param title The title of the gui.
|
||||
* @param parent Parent gui to go back when completed.
|
||||
* @param configPath Configuration path of this setting.
|
||||
* @param config Configuration holder of this setting.
|
||||
* @param defaultVal Default value if not found on the config.
|
||||
* @return A factory for an item setting gui.
|
||||
*/
|
||||
public static ItemSettingGui.ItemSettingFactory itemFactory(@NotNull String title, ValueUpdatableGui parent,
|
||||
String configPath, ConfigHolder config,
|
||||
ItemStack defaultVal) {
|
||||
return new ItemSettingGui.ItemSettingFactory(
|
||||
title, parent,
|
||||
configPath, config,
|
||||
defaultVal);
|
||||
}
|
||||
|
||||
/**
|
||||
* A factory for an item setting gui that hold setting's information.
|
||||
*/
|
||||
public static class ItemSettingFactory extends SettingGuiFactory {
|
||||
@NotNull
|
||||
String title;
|
||||
ValueUpdatableGui parent;
|
||||
ItemStack defaultVal;
|
||||
|
||||
/**
|
||||
* Constructor for an item setting gui factory.
|
||||
*
|
||||
* @param title The title of the gui.
|
||||
* @param parent Parent gui to go back when completed.
|
||||
* @param configPath Configuration path of this setting.
|
||||
* @param config Configuration holder of this setting.
|
||||
* @param defaultVal Default value if not found on the config.
|
||||
*/
|
||||
protected ItemSettingFactory(
|
||||
@NotNull String title, ValueUpdatableGui parent,
|
||||
String configPath, ConfigHolder config,
|
||||
ItemStack defaultVal) {
|
||||
super(configPath, config);
|
||||
this.title = title;
|
||||
this.parent = parent;
|
||||
|
||||
this.defaultVal = defaultVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Get setting's gui title.
|
||||
*/
|
||||
@NotNull
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The configured value for the associated setting.
|
||||
*/
|
||||
public ItemStack getConfiguredValue() {
|
||||
return this.config.getConfig().getItemStack(this.configPath, this.defaultVal);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractSettingGui create() {
|
||||
// Get current value or default
|
||||
ItemStack now = getConfiguredValue();
|
||||
// create new gui
|
||||
return new ItemSettingGui(this, now);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,189 @@
|
|||
package xyz.alexcrea.cuanvil.gui.config.settings.subsetting;
|
||||
|
||||
import com.github.stefvanschie.inventoryframework.gui.GuiItem;
|
||||
import com.github.stefvanschie.inventoryframework.pane.PatternPane;
|
||||
import com.github.stefvanschie.inventoryframework.pane.util.Pattern;
|
||||
import io.delilaheve.CustomAnvil;
|
||||
import kotlin.ranges.IntRange;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import xyz.alexcrea.cuanvil.config.ConfigHolder;
|
||||
import xyz.alexcrea.cuanvil.gui.config.ConfirmActionGui;
|
||||
import xyz.alexcrea.cuanvil.gui.config.global.CustomRecipeConfigGui;
|
||||
import xyz.alexcrea.cuanvil.gui.config.settings.BoolSettingsGui;
|
||||
import xyz.alexcrea.cuanvil.gui.config.settings.IntSettingsGui;
|
||||
import xyz.alexcrea.cuanvil.gui.config.settings.ItemSettingGui;
|
||||
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions;
|
||||
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems;
|
||||
import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant;
|
||||
import xyz.alexcrea.cuanvil.recipe.AnvilCustomRecipe;
|
||||
import xyz.alexcrea.cuanvil.recipe.CustomAnvilRecipeManager;
|
||||
import xyz.alexcrea.cuanvil.util.CasedStringUtil;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class CustomRecipeSubSettingGui extends MappedToListSubSettingGui {
|
||||
|
||||
private final CustomRecipeConfigGui parent;
|
||||
private final AnvilCustomRecipe anvilRecipe;
|
||||
private final PatternPane pane;
|
||||
private boolean shouldWork = true;
|
||||
|
||||
public CustomRecipeSubSettingGui(
|
||||
@NotNull CustomRecipeConfigGui parent,
|
||||
@NotNull AnvilCustomRecipe anvilRecipe,
|
||||
@NotNull GuiItem parentItemForThisGui) {
|
||||
super(parentItemForThisGui, 3, "\u00A7e" + CasedStringUtil.snakeToUpperSpacedCase(anvilRecipe.getName()) + " \u00A78Config");
|
||||
this.parent = parent;
|
||||
this.anvilRecipe = anvilRecipe;
|
||||
|
||||
Pattern pattern = new Pattern(
|
||||
GuiSharedConstant.EMPTY_GUI_FULL_LINE,
|
||||
"01203450D",
|
||||
"B00000000"
|
||||
);
|
||||
this.pane = new PatternPane(0, 0, 9, 3, pattern);
|
||||
addPane(this.pane);
|
||||
|
||||
prepareStaticValues();
|
||||
}
|
||||
|
||||
BoolSettingsGui.BoolSettingFactory exactCountFactory;
|
||||
IntSettingsGui.IntSettingFactory xpCostFactory;
|
||||
ItemSettingGui.ItemSettingFactory leftItemFactory;
|
||||
ItemSettingGui.ItemSettingFactory rightItemFactory;
|
||||
ItemSettingGui.ItemSettingFactory resultItemFactory;
|
||||
|
||||
private void prepareStaticValues() {
|
||||
|
||||
GuiGlobalItems.addBackItem(this.pane, this.parent);
|
||||
GuiGlobalItems.addBackgroundItem(this.pane);
|
||||
|
||||
// Delete item
|
||||
ItemStack deleteItem = new ItemStack(Material.RED_TERRACOTTA);
|
||||
ItemMeta deleteMeta = deleteItem.getItemMeta();
|
||||
|
||||
deleteMeta.setDisplayName("\u00A74DELETE RECIPE");
|
||||
deleteMeta.setLore(Collections.singletonList("\u00A7cCaution with this button !"));
|
||||
|
||||
deleteItem.setItemMeta(deleteMeta);
|
||||
this.pane.bindItem('D', new GuiItem(deleteItem, GuiGlobalActions.openGuiAction(createDeleteGui()), CustomAnvil.instance));
|
||||
|
||||
// Displayed item will be updated later
|
||||
|
||||
IntRange costRange = AnvilCustomRecipe.Companion.getXP_COST_CONFIG_RANGE();
|
||||
this.exactCountFactory = BoolSettingsGui.boolFactory("\u00A78Exact count ?", this,
|
||||
this.anvilRecipe.getName()+"."+AnvilCustomRecipe.EXACT_COUNT_CONFIG, ConfigHolder.CUSTOM_RECIPE_HOLDER,
|
||||
AnvilCustomRecipe.Companion.getDEFAULT_EXACT_COUNT_CONFIG());
|
||||
|
||||
this.xpCostFactory = IntSettingsGui.intFactory("\u00A78Recipe Xp Cost", this,
|
||||
this.anvilRecipe.getName()+"."+AnvilCustomRecipe.XP_COST_CONFIG, ConfigHolder.CUSTOM_RECIPE_HOLDER,
|
||||
costRange.getFirst(), costRange.getLast(), AnvilCustomRecipe.Companion.getDEFAULT_XP_COST_CONFIG(), 1, 5, 10);
|
||||
|
||||
|
||||
this.leftItemFactory = ItemSettingGui.itemFactory("\u00A7eRecipe Left \u00A78Item", this,
|
||||
this.anvilRecipe.getName()+"."+AnvilCustomRecipe.LEFT_ITEM_CONFIG, ConfigHolder.CUSTOM_RECIPE_HOLDER,
|
||||
AnvilCustomRecipe.Companion.getDEFAULT_LEFT_ITEM_CONFIG());
|
||||
|
||||
this.rightItemFactory = ItemSettingGui.itemFactory("\u00A7eRecipe Right \u00A78Item", this,
|
||||
this.anvilRecipe.getName()+"."+AnvilCustomRecipe.RIGHT_ITEM_CONFIG, ConfigHolder.CUSTOM_RECIPE_HOLDER,
|
||||
AnvilCustomRecipe.Companion.getDEFAULT_RIGHT_ITEM_CONFIG());
|
||||
|
||||
this.resultItemFactory = ItemSettingGui.itemFactory("\u00A7aRecipe Result \u00A78Item", this,
|
||||
this.anvilRecipe.getName()+"."+AnvilCustomRecipe.RESULT_ITEM_CONFIG, ConfigHolder.CUSTOM_RECIPE_HOLDER,
|
||||
AnvilCustomRecipe.Companion.getDEFAULT_RESULT_ITEM_CONFIG());
|
||||
}
|
||||
|
||||
private ConfirmActionGui createDeleteGui() {
|
||||
Supplier<Boolean> deleteSupplier = () -> {
|
||||
CustomAnvilRecipeManager manager = ConfigHolder.CUSTOM_RECIPE_HOLDER.getRecipeManager();
|
||||
|
||||
// Remove from manager
|
||||
manager.cleanRemove(this.anvilRecipe);
|
||||
|
||||
// Remove from parent
|
||||
this.parent.removeGeneric(this.anvilRecipe);
|
||||
|
||||
// Remove self
|
||||
cleanUnused();
|
||||
|
||||
// Update config file storage
|
||||
ConfigHolder.CUSTOM_RECIPE_HOLDER.getConfig().set(this.anvilRecipe.getName(), null);
|
||||
|
||||
// Save
|
||||
boolean success = true;
|
||||
if (GuiSharedConstant.TEMPORARY_DO_SAVE_TO_DISK_EVERY_CHANGE) {
|
||||
success = ConfigHolder.CONFLICT_HOLDER.saveToDisk(GuiSharedConstant.TEMPORARY_DO_BACKUP_EVERY_SAVE);
|
||||
}
|
||||
|
||||
return success;
|
||||
};
|
||||
|
||||
return new ConfirmActionGui("\u00A7cDelete \u00A7e" + CasedStringUtil.snakeToUpperSpacedCase(this.anvilRecipe.getName()) + "\u00A7c?",
|
||||
"\u00A77Confirm that you want to delete this conflict.",
|
||||
this, this.parent, deleteSupplier
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateGuiValues() {
|
||||
// update value from config to conflict
|
||||
this.anvilRecipe.updateFromFile();
|
||||
|
||||
// Parent should call updateLocal with this call
|
||||
this.parent.updateValueForGeneric(this.anvilRecipe, true);
|
||||
}
|
||||
|
||||
public void updateLocal() {
|
||||
if (!this.shouldWork) return;
|
||||
|
||||
GuiItem exactCountItem = GuiGlobalItems.boolSettingGuiItem(this.exactCountFactory);
|
||||
this.pane.bindItem('1', exactCountItem);
|
||||
|
||||
GuiItem xpCostItem = GuiGlobalItems.intSettingGuiItem(this.xpCostFactory, Material.EXPERIENCE_BOTTLE);
|
||||
this.pane.bindItem('2', xpCostItem);
|
||||
|
||||
GuiItem leftGuiItem = GuiGlobalItems.itemSettingGuiItem(this.leftItemFactory);
|
||||
this.pane.bindItem('3', leftGuiItem);
|
||||
|
||||
GuiItem rightGuiItem = GuiGlobalItems.itemSettingGuiItem(this.rightItemFactory);
|
||||
this.pane.bindItem('4', rightGuiItem);
|
||||
|
||||
GuiItem resultGuiItem = GuiGlobalItems.itemSettingGuiItem(this.resultItemFactory);
|
||||
this.pane.bindItem('5', resultGuiItem);
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
public void cleanUnused() {
|
||||
for (HumanEntity viewer : getViewers()) {
|
||||
this.parent.show(viewer);
|
||||
}
|
||||
this.shouldWork = false;
|
||||
|
||||
// Just in case something is extremely wrong
|
||||
GuiItem background = GuiGlobalItems.backgroundItem();
|
||||
this.pane.bindItem('1', background);
|
||||
this.pane.bindItem('2', background);
|
||||
this.pane.bindItem('3', background);
|
||||
this.pane.bindItem('4', background);
|
||||
this.pane.bindItem('5', background);
|
||||
|
||||
this.pane.bindItem('D', background);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void show(@NotNull HumanEntity humanEntity) {
|
||||
if (this.shouldWork) {
|
||||
super.show(humanEntity);
|
||||
} else {
|
||||
this.parent.show(humanEntity);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -14,7 +14,6 @@ import xyz.alexcrea.cuanvil.config.ConfigHolder;
|
|||
import xyz.alexcrea.cuanvil.group.AbstractMaterialGroup;
|
||||
import xyz.alexcrea.cuanvil.group.EnchantConflictGroup;
|
||||
import xyz.alexcrea.cuanvil.group.EnchantConflictManager;
|
||||
import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui;
|
||||
import xyz.alexcrea.cuanvil.gui.config.ConfirmActionGui;
|
||||
import xyz.alexcrea.cuanvil.gui.config.SelectEnchantmentContainer;
|
||||
import xyz.alexcrea.cuanvil.gui.config.SelectGroupContainer;
|
||||
|
|
@ -34,24 +33,22 @@ import java.util.Set;
|
|||
import java.util.function.Supplier;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class EnchantConflictSubSettingGui extends ValueUpdatableGui implements SelectEnchantmentContainer, SelectGroupContainer {
|
||||
public class EnchantConflictSubSettingGui extends MappedToListSubSettingGui implements SelectEnchantmentContainer, SelectGroupContainer {
|
||||
|
||||
private final EnchantConflictGui parent;
|
||||
private final EnchantConflictGroup enchantConflict;
|
||||
private final GuiItem parentItemForThisGui;
|
||||
private final PatternPane pane;
|
||||
private boolean shouldWorld = true;
|
||||
private boolean shouldWork = true;
|
||||
|
||||
public EnchantConflictSubSettingGui(
|
||||
@NotNull EnchantConflictGui parent,
|
||||
@NotNull EnchantConflictGroup enchantConflict,
|
||||
@NotNull GuiItem parentItemForThisGui) {
|
||||
super(3,
|
||||
"\u00A7e" + CasedStringUtil.snakeToUpperSpacedCase(enchantConflict.getName()) + " \u00A78Config",
|
||||
CustomAnvil.instance);
|
||||
super(parentItemForThisGui,
|
||||
3,
|
||||
"\u00A7e" + CasedStringUtil.snakeToUpperSpacedCase(enchantConflict.getName()) + " \u00A78Config");
|
||||
this.parent = parent;
|
||||
this.enchantConflict = enchantConflict;
|
||||
this.parentItemForThisGui = parentItemForThisGui;
|
||||
|
||||
Pattern pattern = new Pattern(
|
||||
GuiSharedConstant.EMPTY_GUI_FULL_LINE,
|
||||
|
|
@ -126,7 +123,7 @@ public class EnchantConflictSubSettingGui extends ValueUpdatableGui implements S
|
|||
manager.conflictList.remove(this.enchantConflict);
|
||||
|
||||
// Remove from parent
|
||||
this.parent.removeConflict(this.enchantConflict);
|
||||
this.parent.removeGeneric(this.enchantConflict);
|
||||
|
||||
// Remove self
|
||||
cleanUnused();
|
||||
|
|
@ -143,7 +140,7 @@ public class EnchantConflictSubSettingGui extends ValueUpdatableGui implements S
|
|||
return success;
|
||||
};
|
||||
|
||||
return new ConfirmActionGui("\u00A7cDelete \u00A7e" + CasedStringUtil.snakeToUpperSpacedCase(enchantConflict.getName()) + "\u00A7c?",
|
||||
return new ConfirmActionGui("\u00A7cDelete \u00A7e" + CasedStringUtil.snakeToUpperSpacedCase(this.enchantConflict.getName()) + "\u00A7c?",
|
||||
"\u00A77Confirm that you want to delete this conflict.",
|
||||
this, this.parent, deleteSupplier
|
||||
);
|
||||
|
|
@ -151,12 +148,17 @@ public class EnchantConflictSubSettingGui extends ValueUpdatableGui implements S
|
|||
|
||||
@Override
|
||||
public void updateGuiValues() {
|
||||
this.parent.updateValueForConflict(this.enchantConflict, true);
|
||||
// Parent should call updateLocal
|
||||
// update value from config to conflict
|
||||
int minBeforeBlock = ConfigHolder.CONFLICT_HOLDER.getConfig().getInt(this.enchantConflict.getName()+'.'+EnchantConflictManager.ENCH_MAX_PATH, 0);
|
||||
this.enchantConflict.setMinBeforeBlock(minBeforeBlock);
|
||||
|
||||
// Parent should call updateLocal with this call
|
||||
this.parent.updateValueForGeneric(this.enchantConflict, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateLocal() {
|
||||
if (!this.shouldWorld) return;
|
||||
if (!this.shouldWork) return;
|
||||
|
||||
// Prepare enchantment lore
|
||||
ArrayList<String> enchantLore = new ArrayList<>();
|
||||
|
|
@ -231,11 +233,12 @@ public class EnchantConflictSubSettingGui extends ValueUpdatableGui implements S
|
|||
update();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanUnused() {
|
||||
for (HumanEntity viewer : getViewers()) {
|
||||
this.parent.show(viewer);
|
||||
}
|
||||
this.shouldWorld = false;
|
||||
this.shouldWork = false;
|
||||
|
||||
// Just in case something is extremely wrong
|
||||
GuiItem background = GuiGlobalItems.backgroundItem();
|
||||
|
|
@ -247,17 +250,13 @@ public class EnchantConflictSubSettingGui extends ValueUpdatableGui implements S
|
|||
|
||||
@Override
|
||||
public void show(@NotNull HumanEntity humanEntity) {
|
||||
if (this.shouldWorld) {
|
||||
if (this.shouldWork) {
|
||||
super.show(humanEntity);
|
||||
} else {
|
||||
this.parent.show(humanEntity);
|
||||
}
|
||||
}
|
||||
|
||||
public GuiItem getParentItemForThisGui() {
|
||||
return parentItemForThisGui;
|
||||
}
|
||||
|
||||
// Select enchantment container methods
|
||||
|
||||
@Override
|
||||
|
|
@ -267,7 +266,7 @@ public class EnchantConflictSubSettingGui extends ValueUpdatableGui implements S
|
|||
|
||||
@Override
|
||||
public boolean setSelectedEnchantments(Set<Enchantment> enchantments) {
|
||||
if (!this.shouldWorld) {
|
||||
if (!this.shouldWork) {
|
||||
CustomAnvil.instance.getLogger().info("Trying to save " + enchantConflict.getName() + " enchants but sub config is destroyed");
|
||||
return false;
|
||||
}
|
||||
|
|
@ -312,7 +311,7 @@ public class EnchantConflictSubSettingGui extends ValueUpdatableGui implements S
|
|||
|
||||
@Override
|
||||
public boolean setSelectedGroups(Set<AbstractMaterialGroup> groups) {
|
||||
if (!this.shouldWorld) {
|
||||
if (!this.shouldWork) {
|
||||
CustomAnvil.instance.getLogger().info("Trying to save " + enchantConflict.getName() + " groups but sub config is destroyed");
|
||||
return false;
|
||||
}
|
||||
|
|
@ -347,4 +346,5 @@ public class EnchantConflictSubSettingGui extends ValueUpdatableGui implements S
|
|||
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,28 @@
|
|||
package xyz.alexcrea.cuanvil.gui.config.settings.subsetting;
|
||||
|
||||
import com.github.stefvanschie.inventoryframework.gui.GuiItem;
|
||||
import io.delilaheve.CustomAnvil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui;
|
||||
|
||||
public abstract class MappedToListSubSettingGui extends ValueUpdatableGui {
|
||||
|
||||
private final GuiItem item;
|
||||
public MappedToListSubSettingGui(
|
||||
GuiItem item,
|
||||
int rows,
|
||||
@NotNull String title) {
|
||||
super(rows, title, CustomAnvil.instance);
|
||||
this.item = item;
|
||||
}
|
||||
|
||||
|
||||
public GuiItem getParentItemForThisGui() {
|
||||
return item;
|
||||
}
|
||||
|
||||
|
||||
public abstract void updateLocal(); // TODO
|
||||
|
||||
public abstract void cleanUnused(); // TODO
|
||||
}
|
||||
|
|
@ -12,8 +12,10 @@ import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui;
|
|||
import xyz.alexcrea.cuanvil.gui.config.settings.AbstractSettingGui;
|
||||
import xyz.alexcrea.cuanvil.gui.config.settings.BoolSettingsGui;
|
||||
import xyz.alexcrea.cuanvil.gui.config.settings.IntSettingsGui;
|
||||
import xyz.alexcrea.cuanvil.gui.config.settings.ItemSettingGui;
|
||||
import xyz.alexcrea.cuanvil.util.CasedStringUtil;
|
||||
|
||||
import java.nio.charset.MalformedInputException;
|
||||
import java.util.Collections;
|
||||
|
||||
/**
|
||||
|
|
@ -264,6 +266,48 @@ public class GuiGlobalItems {
|
|||
return intSettingGuiItem(factory, itemMat, CasedStringUtil.detectToUpperSpacedCase(configPath));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new item setting GuiItem.
|
||||
* This item will create and open an item setting GUI from the factory.
|
||||
* Item's name will be the factory set title.
|
||||
*
|
||||
* @param factory The setting's GUI factory.
|
||||
* @param name Name of the item.
|
||||
* @return A formatted GuiItem that will create and open a GUI for the item setting.
|
||||
*/
|
||||
public static GuiItem itemSettingGuiItem(
|
||||
@NotNull ItemSettingGui.ItemSettingFactory factory,
|
||||
@NotNull String name
|
||||
) {
|
||||
ItemStack item = factory.getConfiguredValue();
|
||||
if(item == null || item.getType().isAir()){
|
||||
item = new ItemStack(Material.BARRIER);
|
||||
}else{
|
||||
item = item.clone();
|
||||
}
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
meta.setDisplayName("\u00A7a" + name);
|
||||
|
||||
item.setItemMeta(meta);
|
||||
|
||||
return openSettingGuiItem(item, factory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new item setting GuiItem.
|
||||
* This item will create and open an item setting GUI from the factory.
|
||||
* Item's name will be the factory set title.
|
||||
*
|
||||
* @param factory The setting's GUI factory.
|
||||
* @return A formatted GuiItem that will create and open a GUI for the item setting.
|
||||
*/
|
||||
public static GuiItem itemSettingGuiItem(
|
||||
@NotNull ItemSettingGui.ItemSettingFactory factory
|
||||
) {
|
||||
String configPath = getConfigNameFromPath(factory.getConfigPath());
|
||||
return itemSettingGuiItem(factory, CasedStringUtil.detectToUpperSpacedCase(configPath));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an arbitrary GuiItem from a unique setting and item's property.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import org.bukkit.inventory.ItemStack
|
|||
import org.bukkit.inventory.meta.Repairable
|
||||
import xyz.alexcrea.cuanvil.config.ConfigHolder
|
||||
import xyz.alexcrea.cuanvil.group.ConflictType
|
||||
import xyz.alexcrea.cuanvil.recipe.AnvilCustomRecipe
|
||||
import xyz.alexcrea.cuanvil.util.UnitRepairUtil.getRepair
|
||||
import kotlin.math.min
|
||||
|
||||
|
|
@ -58,6 +59,21 @@ class AnvilEventListener : Listener {
|
|||
val player = event.view.player
|
||||
if (!player.hasPermission(CustomAnvil.affectedByPluginPermission)) return
|
||||
|
||||
// Test custom recipe
|
||||
val recipe = getCustomRecipe(first, second)
|
||||
CustomAnvil.verboseLog("custom recipe not null? ${recipe != null}")
|
||||
if(recipe != null){
|
||||
val amount = getCustomRecipeAmount(recipe, first, second)
|
||||
|
||||
val resultItem: ItemStack = recipe.resultItem!!.clone()
|
||||
resultItem.amount *= amount
|
||||
|
||||
event.result = resultItem
|
||||
handleAnvilXp(inventory, event, recipe.xpCostPerCraft * amount, true)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Test rename lonely item
|
||||
if (second == null) {
|
||||
val resultItem = first.clone()
|
||||
|
|
@ -139,6 +155,7 @@ class AnvilEventListener : Listener {
|
|||
CustomAnvil.log("no anvil fuse type found")
|
||||
event.result = null
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun handleRename(resultItem: ItemStack, inventory: AnvilInventory): Int {
|
||||
|
|
@ -168,6 +185,16 @@ class AnvilEventListener : Listener {
|
|||
val leftItem = inventory.getItem(ANVIL_INPUT_LEFT) ?: return
|
||||
val rightItem = inventory.getItem(ANVIL_INPUT_RIGHT)
|
||||
|
||||
// Test custom recipe
|
||||
val recipe = getCustomRecipe(leftItem, rightItem)
|
||||
if(recipe != null){
|
||||
event.result = Event.Result.ALLOW
|
||||
onCustomCraft(
|
||||
event, recipe, player,
|
||||
leftItem, rightItem, output, inventory)
|
||||
return
|
||||
}
|
||||
|
||||
val canMerge = leftItem.canMergeWith(rightItem)
|
||||
val unitRepairResult = leftItem.getRepair(rightItem)
|
||||
val allowed = (rightItem == null)
|
||||
|
|
@ -198,6 +225,70 @@ class AnvilEventListener : Listener {
|
|||
}
|
||||
}
|
||||
|
||||
private fun onCustomCraft(event: InventoryClickEvent,
|
||||
recipe: AnvilCustomRecipe,
|
||||
player: Player,
|
||||
leftItem: ItemStack,
|
||||
rightItem: ItemStack?,
|
||||
output: ItemStack,
|
||||
inventory: AnvilInventory) {
|
||||
event.result = Event.Result.DENY
|
||||
|
||||
if(recipe.leftItem == null) return // in case it changed
|
||||
|
||||
val amount = getCustomRecipeAmount(recipe, leftItem, rightItem)
|
||||
val xpCost = amount * recipe.xpCostPerCraft
|
||||
|
||||
if ((player.gameMode != GameMode.CREATIVE) && (player.level < xpCost)) return
|
||||
|
||||
// We give the item manually
|
||||
// But first we check if we should give the item
|
||||
val slotDestination = getActionSlot(event, player)
|
||||
if (slotDestination.type == SlotType.NO_SLOT) return
|
||||
|
||||
// If not creative middle click...
|
||||
if (event.click != ClickType.MIDDLE) {
|
||||
// We remove what should be removed
|
||||
leftItem.amount -= amount * recipe.leftItem!!.amount
|
||||
inventory.setItem(ANVIL_INPUT_LEFT, leftItem)
|
||||
|
||||
if(rightItem != null){
|
||||
if(recipe.rightItem == null) return // in case it changed
|
||||
|
||||
rightItem.amount -= amount * recipe.rightItem!!.amount
|
||||
inventory.setItem(ANVIL_INPUT_RIGHT, rightItem)
|
||||
}
|
||||
player.level -= amount
|
||||
|
||||
// Then we try to find the new values for the anvil
|
||||
val newAmount = getCustomRecipeAmount(recipe, leftItem, rightItem)
|
||||
|
||||
CustomAnvil.verboseLog("new amount is $newAmount")
|
||||
if(newAmount <= 0 || recipe.exactCount){
|
||||
inventory.setItem(ANVIL_OUTPUT_SLOT, null)
|
||||
}else{
|
||||
val resultItem: ItemStack = recipe.resultItem!!.clone()
|
||||
resultItem.amount *= newAmount
|
||||
|
||||
val newXp = newAmount * newAmount
|
||||
|
||||
inventory.repairCost = newXp
|
||||
event.view.setProperty(REPAIR_COST, newXp)
|
||||
|
||||
inventory.setItem(ANVIL_OUTPUT_SLOT, resultItem)
|
||||
}
|
||||
}
|
||||
|
||||
// Finally, we add the item to the player
|
||||
if (slotDestination.type == SlotType.CURSOR) {
|
||||
player.setItemOnCursor(output)
|
||||
} else {// We assume SlotType == SlotType.INVENTORY
|
||||
player.inventory.setItem(slotDestination.slot, output)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private fun onUnitRepairExtract(
|
||||
leftItem: ItemStack,
|
||||
rightItem: ItemStack,
|
||||
|
|
@ -370,16 +461,61 @@ class AnvilEventListener : Listener {
|
|||
return rightValue + illegalPenalty
|
||||
}
|
||||
|
||||
private fun getCustomRecipe (
|
||||
leftItem: ItemStack,
|
||||
rightItem: ItemStack?) : AnvilCustomRecipe? {
|
||||
|
||||
val recipeList = ConfigHolder.CUSTOM_RECIPE_HOLDER.recipeManager.recipeByMat[leftItem.type] ?: return null
|
||||
|
||||
CustomAnvil.verboseLog("Testing " + recipeList.size+" recipe...")
|
||||
for (recipe in recipeList) {
|
||||
if(recipe.testItem(leftItem, rightItem)){
|
||||
return recipe
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
private fun getCustomRecipeAmount(
|
||||
recipe: AnvilCustomRecipe,
|
||||
leftItem: ItemStack,
|
||||
rightItem: ItemStack?
|
||||
): Int{
|
||||
return if(recipe.exactCount) {
|
||||
if(leftItem.amount != recipe.leftItem!!.amount){
|
||||
0
|
||||
}else if(rightItem != null && rightItem.amount != recipe.rightItem!!.amount){
|
||||
0
|
||||
}else{
|
||||
1
|
||||
}
|
||||
}
|
||||
else {
|
||||
// test amount
|
||||
val resultItem = recipe.resultItem!! // we know exist as the recipe was returned to us
|
||||
val maxResultAmount = resultItem.type.maxStackSize/resultItem.amount
|
||||
val maxLeftAmount = leftItem.amount/recipe.leftItem!!.amount
|
||||
val maxRightAmount = if(rightItem == null){ maxLeftAmount } else{ rightItem.amount/recipe.rightItem!!.amount }
|
||||
|
||||
CustomAnvil.verboseLog("resultItem: $resultItem, maxResultAmount: $maxResultAmount, maxLeftAmount: $maxLeftAmount, maxRightAmount: $maxRightAmount")
|
||||
|
||||
min(min(maxResultAmount, maxLeftAmount), maxRightAmount)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Display xp needed for the work on the anvil inventory
|
||||
*/
|
||||
private fun handleAnvilXp(
|
||||
inventory: AnvilInventory,
|
||||
event: PrepareAnvilEvent,
|
||||
anvilCost: Int
|
||||
anvilCost: Int,
|
||||
ignoreRules: Boolean = false
|
||||
) {
|
||||
// Test repair cost limit
|
||||
val finalAnvilCost = if (ConfigOptions.limitRepairCost) {
|
||||
val finalAnvilCost = if (ConfigOptions.limitRepairCost && !ignoreRules) {
|
||||
min(anvilCost, ConfigOptions.limitRepairValue)
|
||||
} else {
|
||||
anvilCost
|
||||
|
|
@ -392,8 +528,10 @@ class AnvilEventListener : Listener {
|
|||
.server
|
||||
.scheduler
|
||||
.runTask(CustomAnvil.instance, Runnable {
|
||||
if (ConfigOptions.removeRepairLimit) {
|
||||
if (ConfigOptions.removeRepairLimit || ignoreRules) {
|
||||
inventory.maximumRepairCost = Int.MAX_VALUE
|
||||
} else{
|
||||
inventory.maximumRepairCost = 40 // minecraft default
|
||||
}
|
||||
inventory.repairCost = finalAnvilCost
|
||||
|
||||
|
|
|
|||
|
|
@ -3,12 +3,13 @@ package xyz.alexcrea.cuanvil.group
|
|||
import io.delilaheve.CustomAnvil
|
||||
import org.bukkit.Material
|
||||
import org.bukkit.enchantments.Enchantment
|
||||
import xyz.alexcrea.cuanvil.interfaces.Named
|
||||
|
||||
class EnchantConflictGroup(
|
||||
val name: String,
|
||||
private val name: String,
|
||||
private val cantConflict: AbstractMaterialGroup,
|
||||
val minBeforeBlock: Int
|
||||
) {
|
||||
var minBeforeBlock: Int
|
||||
): Named {
|
||||
|
||||
private val enchantments = HashSet<Enchantment>()
|
||||
|
||||
|
|
@ -62,4 +63,8 @@ class EnchantConflictGroup(
|
|||
return Material.ENCHANTED_BOOK
|
||||
}
|
||||
|
||||
override fun getName(): String {
|
||||
return name
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -139,9 +139,9 @@ class EnchantConflictManager {
|
|||
|
||||
var result = ConflictType.NO_CONFLICT
|
||||
for (conflict in conflictList) {
|
||||
CustomAnvil.verboseLog("Is against ${conflict.name}")
|
||||
CustomAnvil.verboseLog("Is against ${conflict.getName()}")
|
||||
val conflicting = conflict.allowed(base, mat)
|
||||
CustomAnvil.verboseLog("Was against ${conflict.name} and conflicting: $conflicting ")
|
||||
CustomAnvil.verboseLog("Was against ${conflict.getName()} and conflicting: $conflicting ")
|
||||
if (!conflicting) {
|
||||
if (conflict.getEnchants().size <= 1) {
|
||||
result = ConflictType.SMALL_CONFLICT
|
||||
|
|
|
|||
7
src/main/kotlin/xyz/alexcrea/cuanvil/interfaces/Named.kt
Normal file
7
src/main/kotlin/xyz/alexcrea/cuanvil/interfaces/Named.kt
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
package xyz.alexcrea.cuanvil.interfaces
|
||||
|
||||
interface Named {
|
||||
|
||||
fun getName(): String
|
||||
|
||||
}
|
||||
170
src/main/kotlin/xyz/alexcrea/cuanvil/recipe/AnvilCustomRecipe.kt
Normal file
170
src/main/kotlin/xyz/alexcrea/cuanvil/recipe/AnvilCustomRecipe.kt
Normal file
|
|
@ -0,0 +1,170 @@
|
|||
package xyz.alexcrea.cuanvil.recipe
|
||||
|
||||
import io.delilaheve.CustomAnvil
|
||||
import org.bukkit.configuration.ConfigurationSection
|
||||
import org.bukkit.inventory.ItemStack
|
||||
import xyz.alexcrea.cuanvil.config.ConfigHolder
|
||||
import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant
|
||||
import xyz.alexcrea.cuanvil.interfaces.Named
|
||||
|
||||
class AnvilCustomRecipe(
|
||||
private val name: String,
|
||||
var exactCount: Boolean,
|
||||
//var exactLeft: Boolean,
|
||||
//var exactRight: Boolean,
|
||||
|
||||
var xpCostPerCraft: Int,
|
||||
|
||||
var leftItem: ItemStack?,
|
||||
var rightItem: ItemStack?,
|
||||
var resultItem: ItemStack?,
|
||||
): Named {
|
||||
|
||||
// Static config name
|
||||
companion object {
|
||||
const val EXACT_COUNT_CONFIG = "exact_count"
|
||||
//const val EXACT_LEFT_CONFIG = "exact_left"
|
||||
//const val EXACT_RIGHT_CONFIG = "exact_right"
|
||||
|
||||
const val XP_COST_CONFIG = "xp_cost"
|
||||
|
||||
const val LEFT_ITEM_CONFIG = "left_item"
|
||||
const val RIGHT_ITEM_CONFIG = "right_item"
|
||||
const val RESULT_ITEM_CONFIG = "result_item"
|
||||
|
||||
|
||||
val DEFAULT_EXACT_COUNT_CONFIG = true
|
||||
//val DEFAULT_EXACT_LEFT_CONFIG = true
|
||||
//val DEFAULT_EXACT_RIGHT_CONFIG = true
|
||||
|
||||
val DEFAULT_XP_COST_CONFIG = 1
|
||||
|
||||
val DEFAULT_LEFT_ITEM_CONFIG: ItemStack? = null
|
||||
val DEFAULT_RIGHT_ITEM_CONFIG: ItemStack? = null
|
||||
val DEFAULT_RESULT_ITEM_CONFIG: ItemStack? = null;
|
||||
|
||||
val XP_COST_CONFIG_RANGE = 0..255
|
||||
|
||||
fun getFromConfig(name: String, configSection: ConfigurationSection?): AnvilCustomRecipe? {
|
||||
if(configSection == null) return null;
|
||||
return AnvilCustomRecipe(
|
||||
name,
|
||||
configSection.getBoolean(EXACT_COUNT_CONFIG, DEFAULT_EXACT_COUNT_CONFIG),
|
||||
//configSection.getBoolean(EXACT_LEFT_CONFIG, true),
|
||||
//configSection.getBoolean(EXACT_RIGHT_CONFIG, true),
|
||||
|
||||
configSection.getInt(XP_COST_CONFIG, DEFAULT_XP_COST_CONFIG),
|
||||
|
||||
configSection.getItemStack(LEFT_ITEM_CONFIG, DEFAULT_LEFT_ITEM_CONFIG),
|
||||
configSection.getItemStack(RIGHT_ITEM_CONFIG, DEFAULT_RIGHT_ITEM_CONFIG),
|
||||
configSection.getItemStack(RESULT_ITEM_CONFIG, DEFAULT_RESULT_ITEM_CONFIG),
|
||||
|
||||
)
|
||||
}
|
||||
|
||||
fun getFromConfig(name: String): AnvilCustomRecipe? {
|
||||
return getFromConfig(name, ConfigHolder.CUSTOM_RECIPE_HOLDER.config.getConfigurationSection(name))
|
||||
}
|
||||
}
|
||||
|
||||
fun validate(): Boolean {
|
||||
return (leftItem != null) && !(leftItem!!.type.isAir) && (leftItem!!.amount > 0) &&
|
||||
//(rightItem != null) && !(rightItem!!.type.isAir) && (rightItem!!.amount > 0) &&
|
||||
((rightItem == null) || (!(rightItem!!.type.isAir) && (rightItem!!.amount > 0))) &&
|
||||
(resultItem != null) && !(resultItem!!.type.isAir) && (resultItem!!.amount > 0)
|
||||
|
||||
}
|
||||
|
||||
fun saveToFile(){
|
||||
val fileConfig = ConfigHolder.CUSTOM_RECIPE_HOLDER.config
|
||||
|
||||
fileConfig.set("$name.$EXACT_COUNT_CONFIG", exactCount)
|
||||
//fileConfig.set("$name.$EXACT_LEFT_CONFIG", exactLeft)
|
||||
//fileConfig.set("$name.$EXACT_RIGHT_CONFIG", exactRight)
|
||||
|
||||
fileConfig.set("$name.$XP_COST_CONFIG", xpCostPerCraft)
|
||||
|
||||
fileConfig.set("$name.$LEFT_ITEM_CONFIG", leftItem)
|
||||
fileConfig.set("$name.$RIGHT_ITEM_CONFIG", rightItem)
|
||||
fileConfig.set("$name.$RESULT_ITEM_CONFIG", resultItem)
|
||||
|
||||
|
||||
if (GuiSharedConstant.TEMPORARY_DO_SAVE_TO_DISK_EVERY_CHANGE) {
|
||||
ConfigHolder.CUSTOM_RECIPE_HOLDER.saveToDisk(GuiSharedConstant.TEMPORARY_DO_BACKUP_EVERY_SAVE);
|
||||
}
|
||||
}
|
||||
|
||||
fun updateFromFile(){
|
||||
this.exactCount = ConfigHolder.CUSTOM_RECIPE_HOLDER.config.getBoolean(
|
||||
"$name.$EXACT_COUNT_CONFIG",
|
||||
DEFAULT_EXACT_COUNT_CONFIG
|
||||
)
|
||||
|
||||
this.xpCostPerCraft = ConfigHolder.CUSTOM_RECIPE_HOLDER.config.getInt(
|
||||
"$name.$XP_COST_CONFIG",
|
||||
DEFAULT_XP_COST_CONFIG
|
||||
)
|
||||
|
||||
// Update items
|
||||
val leftItem = ConfigHolder.CUSTOM_RECIPE_HOLDER.config.getItemStack(
|
||||
"$name.$LEFT_ITEM_CONFIG",
|
||||
DEFAULT_LEFT_ITEM_CONFIG
|
||||
)
|
||||
|
||||
this.rightItem = ConfigHolder.CUSTOM_RECIPE_HOLDER.config.getItemStack(
|
||||
"$name.$RIGHT_ITEM_CONFIG",
|
||||
DEFAULT_RIGHT_ITEM_CONFIG
|
||||
)
|
||||
|
||||
this.resultItem = ConfigHolder.CUSTOM_RECIPE_HOLDER.config.getItemStack(
|
||||
"$name.$RESULT_ITEM_CONFIG",
|
||||
DEFAULT_RESULT_ITEM_CONFIG
|
||||
)
|
||||
|
||||
// Update material map
|
||||
ConfigHolder.CUSTOM_RECIPE_HOLDER.recipeManager.cleanSetLeftItem(this, leftItem)
|
||||
|
||||
}
|
||||
|
||||
fun testItem(item1: ItemStack, item2: ItemStack?): Boolean {
|
||||
CustomAnvil.verboseLog("Testing $name $leftItem")
|
||||
// We assume this function can be call only if leftItem != null
|
||||
|
||||
// Test is valid
|
||||
if(!validate()) return false
|
||||
|
||||
val leftSimilar = leftItem!!.isSimilar(item1)
|
||||
CustomAnvil.verboseLog("Validated test !")
|
||||
|
||||
// test of left item
|
||||
if(!leftSimilar) return false // Test similar
|
||||
if(exactCount){
|
||||
if((leftItem!!.amount != item1.amount)) return false // test exact amount
|
||||
}else if(item1.amount < leftItem!!.amount) return false // test if it has at least the amount we ask
|
||||
|
||||
CustomAnvil.verboseLog("Left item passed !")
|
||||
|
||||
// we don't know if right item can be
|
||||
if(rightItem == null){ // null test
|
||||
if(item2 != null) return false
|
||||
}else {
|
||||
val rightSimilar = rightItem!!.isSimilar(item2)
|
||||
CustomAnvil.verboseLog("Right similar: $rightSimilar")
|
||||
if(!rightSimilar) return false // test if similar when not null
|
||||
|
||||
if(exactCount) {
|
||||
if (rightItem!!.amount != item2!!.amount) return false // test exact amount
|
||||
}else if(item2!!.amount < rightItem!!.amount) return false // test if it has at least the amount we ask
|
||||
}
|
||||
|
||||
CustomAnvil.verboseLog("Right item passed !")
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun getName(): String {
|
||||
return name
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
package xyz.alexcrea.cuanvil.recipe
|
||||
|
||||
import io.delilaheve.CustomAnvil
|
||||
import org.bukkit.Material
|
||||
import org.bukkit.configuration.file.FileConfiguration
|
||||
import org.bukkit.inventory.ItemStack
|
||||
|
||||
class CustomAnvilRecipeManager {
|
||||
|
||||
lateinit var recipeList: ArrayList<AnvilCustomRecipe>
|
||||
|
||||
lateinit var recipeByMat: LinkedHashMap<Material, ArrayList<AnvilCustomRecipe>>
|
||||
|
||||
fun prepareRecipes(config: FileConfiguration) {
|
||||
recipeList = ArrayList()
|
||||
recipeByMat = LinkedHashMap()
|
||||
|
||||
// read all configs
|
||||
val keys = config.getKeys(false)
|
||||
for (key in keys) {
|
||||
val recipe = AnvilCustomRecipe.getFromConfig(key)
|
||||
if(recipe == null){
|
||||
CustomAnvil.log("Can't load recipe $key")
|
||||
continue
|
||||
}
|
||||
|
||||
cleanAddNew(recipe)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
fun cleanAddNew(recipe: AnvilCustomRecipe){
|
||||
recipeList.add(recipe)
|
||||
val leftItem = recipe.leftItem
|
||||
if(leftItem != null){
|
||||
addToMatMap(recipe, leftItem)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun cleanSetLeftItem(recipe: AnvilCustomRecipe, leftItem: ItemStack?){
|
||||
// Remove left item mat if exist
|
||||
val oldLeftItem = recipe.leftItem
|
||||
if(oldLeftItem != null){
|
||||
val oldMat = oldLeftItem.type
|
||||
|
||||
val test = recipeByMat[oldMat]
|
||||
test!!.remove(recipe)
|
||||
}
|
||||
if(leftItem != null){
|
||||
addToMatMap(recipe, leftItem)
|
||||
}
|
||||
|
||||
recipe.leftItem = leftItem
|
||||
}
|
||||
|
||||
private fun addToMatMap(recipe: AnvilCustomRecipe, leftItem: ItemStack){
|
||||
var recipeList = recipeByMat[leftItem.type]
|
||||
if(recipeList == null){
|
||||
recipeList = ArrayList()
|
||||
recipeByMat[leftItem.type] = recipeList
|
||||
}
|
||||
recipeList.add(recipe)
|
||||
|
||||
}
|
||||
|
||||
fun cleanRemove(recipe: AnvilCustomRecipe) {
|
||||
|
||||
recipeList.remove(recipe)
|
||||
cleanSetLeftItem(recipe, null)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -13,18 +13,21 @@ object MetricsUtil {
|
|||
private const val enchantConflictConfigHash = 1406650190
|
||||
private const val itemGroupsConfigHash = 1406650190
|
||||
private const val unitRepairItemConfigHash = 536871958
|
||||
private const val customAnvilCraftConfigHash = 0
|
||||
private const val baseConfigPieName = "isDefaultBaseConfig"
|
||||
private const val enchantLimitsConfigPieName = "isDefaultEnchantLimitsConfig"
|
||||
private const val enchantValuesConfigPieName = "isDefaultEnchantValuesConfig"
|
||||
private const val enchantConflictConfigPieName = "isDefaultEnchantConflictConfig"
|
||||
private const val itemGroupsConfigPieName = "isDefaultItemGroupsConfig"
|
||||
private const val unitRepairItemConfigPieName = "isDefaultUnitRepairItemConfig"
|
||||
private const val customAnvilCraftConfigPieName = "isDefaultCustomAnvilCraftConfig"
|
||||
private var isDefaultBaseConfig = true
|
||||
private var isDefaultEnchantLimitsConfig = true
|
||||
private var isDefaultEnchantValuesConfig = true
|
||||
private var isDefaultEnchantConflictConfig = true
|
||||
private var isDefaultItemGroupsConfig = true
|
||||
private var isDefaultUnitRepairItemConfig = true
|
||||
private var isDefaultCustomAnvilCraftConfig = true
|
||||
|
||||
/**
|
||||
* Get hash of a key, value a pair of a configuration section
|
||||
|
|
@ -73,6 +76,7 @@ object MetricsUtil {
|
|||
val enchantConflictConfig = getConfigurationHash(ConfigHolder.CONFLICT_HOLDER.config)
|
||||
val itemGroupConfig = getConfigurationHash(ConfigHolder.ITEM_GROUP_HOLDER.config)
|
||||
val unitRepairConfig = getConfigurationHash(ConfigHolder.UNIT_REPAIR_HOLDER.config)
|
||||
val customRecipeConfig = getConfigurationHash(ConfigHolder.CUSTOM_RECIPE_HOLDER.config)
|
||||
// Test if default
|
||||
isDefaultBaseConfig = baseConfigHash == baseConfig
|
||||
isDefaultEnchantLimitsConfig = enchantLimitsConfigHash == limitEnchantConfig
|
||||
|
|
@ -80,6 +84,7 @@ object MetricsUtil {
|
|||
isDefaultEnchantConflictConfig = enchantConflictConfigHash == enchantConflictConfig
|
||||
isDefaultItemGroupsConfig = itemGroupsConfigHash == itemGroupConfig
|
||||
isDefaultUnitRepairItemConfig = unitRepairItemConfigHash == unitRepairConfig
|
||||
isDefaultCustomAnvilCraftConfig = customAnvilCraftConfigHash == customRecipeConfig
|
||||
// If not default and debug flag active, print the hash.
|
||||
if (ConfigOptions.debugLog) {
|
||||
if (!isDefaultBaseConfig) {
|
||||
|
|
@ -100,6 +105,9 @@ object MetricsUtil {
|
|||
if (!isDefaultUnitRepairItemConfig) {
|
||||
CustomAnvil.log("unitRepairConfig: $unitRepairConfig")
|
||||
}
|
||||
if (!isDefaultCustomAnvilCraftConfig) {
|
||||
CustomAnvil.log("customRecipeConfig: $customRecipeConfig")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -141,6 +149,9 @@ object MetricsUtil {
|
|||
metric.addCustomChart(Metrics.SimplePie(unitRepairItemConfigPieName) {
|
||||
isDefaultUnitRepairItemConfig.toString()
|
||||
})
|
||||
metric.addCustomChart(Metrics.SimplePie(customAnvilCraftConfigPieName) {
|
||||
isDefaultCustomAnvilCraftConfig.toString()
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
5
src/main/resources/custom_recipes.yml
Normal file
5
src/main/resources/custom_recipes.yml
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
# ----------------------------------------------------
|
||||
# This config file is to store custom craft
|
||||
# It is recommended to use the in game config editor for this configuration.
|
||||
# /customanvilconfig With ca.config.edit permission
|
||||
# ----------------------------------------------------
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
main: io.delilaheve.CustomAnvil
|
||||
name: CustomAnvil
|
||||
prefix: "Custom Anvil"
|
||||
version: 1.3.2-A2
|
||||
version: 1.4.0a
|
||||
description: Allow to customise anvil mechanics
|
||||
api-version: 1.18
|
||||
load: POSTWORLD
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue