All checks were successful
EpicKnarvik97/Blacksmith/pipeline/head This commit looks good
380 lines
17 KiB
Java
380 lines
17 KiB
Java
package net.knarcraft.blacksmith.trait;
|
|
|
|
import net.citizensnpcs.api.util.DataKey;
|
|
import net.knarcraft.blacksmith.BlacksmithPlugin;
|
|
import net.knarcraft.blacksmith.config.SmithPreset;
|
|
import net.knarcraft.blacksmith.config.SmithPresetFilter;
|
|
import net.knarcraft.blacksmith.config.scrapper.GlobalScrapperSettings;
|
|
import net.knarcraft.blacksmith.config.scrapper.ScrapperNPCSettings;
|
|
import net.knarcraft.blacksmith.config.scrapper.ScrapperSetting;
|
|
import net.knarcraft.blacksmith.container.RecipeResult;
|
|
import net.knarcraft.blacksmith.container.SalvageResult;
|
|
import net.knarcraft.blacksmith.manager.EconomyManager;
|
|
import net.knarcraft.blacksmith.property.SalvageMethod;
|
|
import net.knarcraft.blacksmith.property.SalvageState;
|
|
import net.knarcraft.blacksmith.util.ItemHelper;
|
|
import net.knarcraft.blacksmith.util.SalvageHelper;
|
|
import net.knarcraft.knarlib.formatting.StringFormatter;
|
|
import net.knarcraft.knarlib.formatting.StringReplacer;
|
|
import org.bukkit.Bukkit;
|
|
import org.bukkit.Material;
|
|
import org.bukkit.entity.Player;
|
|
import org.bukkit.inventory.ItemStack;
|
|
import org.bukkit.inventory.meta.ArmorMeta;
|
|
import org.bukkit.inventory.meta.EnchantmentStorageMeta;
|
|
import org.jetbrains.annotations.NotNull;
|
|
import org.jetbrains.annotations.Nullable;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.HashSet;
|
|
import java.util.List;
|
|
import java.util.Set;
|
|
|
|
import static net.knarcraft.blacksmith.formatting.BlacksmithStringFormatter.sendNPCMessage;
|
|
|
|
/**
|
|
* The class representing a scrapper NPC trait
|
|
*/
|
|
public class ScrapperTrait extends CustomTrait<ScrapperSetting> {
|
|
|
|
private final ScrapperNPCSettings config;
|
|
|
|
/**
|
|
* Instantiates a new blacksmith trait
|
|
*/
|
|
public ScrapperTrait() {
|
|
super("scrapper");
|
|
//This should crash if the blacksmith plugin hasn't been properly registered
|
|
Bukkit.getServer().getPluginManager().getPlugin("Blacksmith");
|
|
this.config = new ScrapperNPCSettings(BlacksmithPlugin.getInstance().getGlobalScrapperSettings());
|
|
super.setTraitSettings(this.config);
|
|
}
|
|
|
|
/**
|
|
* Gets the current settings for this NPC
|
|
*
|
|
* @return <p>The current settings for this NPC</p>
|
|
*/
|
|
@NotNull
|
|
public ScrapperNPCSettings getSettings() {
|
|
return config;
|
|
}
|
|
|
|
/**
|
|
* Loads all config values stored in citizens' config file for this NPC
|
|
*
|
|
* @param key <p>The data key used for the config root</p>
|
|
*/
|
|
@Override
|
|
public void load(@NotNull DataKey key) {
|
|
getSettings().loadVariables(key);
|
|
}
|
|
|
|
/**
|
|
* Saves all config values for this NPC
|
|
*
|
|
* @param key <p>The data key used for the config root</p>
|
|
*/
|
|
@Override
|
|
public void save(@NotNull DataKey key) {
|
|
getSettings().saveVariables(key);
|
|
}
|
|
|
|
/**
|
|
* Starts a new session, and prepares to repair the player's item
|
|
*
|
|
* @param player <p>The player to start the session for</p>
|
|
*/
|
|
public void startSession(@NotNull Player player) {
|
|
ItemStack itemInHand = player.getInventory().getItemInMainHand().clone();
|
|
if (itemInHand.getType().isAir()) {
|
|
sendNPCMessage(this.npc, player, config.getNoItemMessage());
|
|
return;
|
|
}
|
|
|
|
List<Material> salvageAbleItems = getSettings().getSalvageAbleItems();
|
|
boolean extended = getSettings().extendedSalvageEnabled();
|
|
|
|
// Check if the item can be salvaged
|
|
if (!canBeSalvaged(itemInHand, salvageAbleItems, extended)) {
|
|
sendNPCMessage(this.npc, player, StringFormatter.replacePlaceholder(getSettings().getInvalidItemMessage(),
|
|
"{title}", getSettings().getScrapperTitle()));
|
|
BlacksmithPlugin.debug("Cannot salvage provided item: " + itemInHand);
|
|
return;
|
|
}
|
|
|
|
SalvageResult result = getBestResult(player, itemInHand, extended);
|
|
|
|
if (result == null || result.salvage().isEmpty()) {
|
|
return;
|
|
}
|
|
|
|
//Start a new scrapper session for the player
|
|
currentSessionStartTime = System.currentTimeMillis();
|
|
try {
|
|
session = new SalvageSession(this, player, npc, getSettings(), result.salvage(),
|
|
result.salvageMethod(), result.requiredAmount());
|
|
} catch (IllegalArgumentException exception) {
|
|
BlacksmithPlugin.error(exception.getMessage());
|
|
return;
|
|
}
|
|
// Print the cost to the player
|
|
printCostMessage(player, itemInHand, EconomyManager.formatSalvageCost(result.salvageMethod(), itemInHand, player),
|
|
result.salvageMethod());
|
|
}
|
|
|
|
/**
|
|
* Gets the best available salvage result
|
|
*
|
|
* @param player <p>The player attempting to salvage an item</p>
|
|
* @param itemInHand <p>The item the player is attempting to salvage</p>
|
|
* @param extended <p>Whether extended salvage is enabled</p>
|
|
* @return <p>The best result, or null if no valid result exists</p>
|
|
*/
|
|
@Nullable
|
|
private SalvageResult getBestResult(@NotNull Player player, @NotNull ItemStack itemInHand, boolean extended) {
|
|
SalvageResult result = isArmorTrimSalvage(player, itemInHand);
|
|
if (result.salvageState() == SalvageState.NO_SALVAGE) {
|
|
return null;
|
|
} else if (result.salvageState() == SalvageState.FOUND_SALVAGE) {
|
|
return result;
|
|
}
|
|
|
|
result = isNetheriteSalvage(player, itemInHand);
|
|
if (result.salvageState() == SalvageState.NO_SALVAGE) {
|
|
return null;
|
|
} else if (result.salvageState() == SalvageState.FOUND_SALVAGE) {
|
|
return result;
|
|
}
|
|
|
|
result = isEnchantedBookSalvage(player, itemInHand);
|
|
if (result.salvageState() == SalvageState.NO_SALVAGE) {
|
|
return null;
|
|
} else if (result.salvageState() == SalvageState.FOUND_SALVAGE) {
|
|
return result;
|
|
}
|
|
|
|
result = isNormalSalvage(player, itemInHand, extended);
|
|
if (result.salvageState() == SalvageState.NO_SALVAGE) {
|
|
return null;
|
|
} else if (result.salvageState() == SalvageState.FOUND_SALVAGE) {
|
|
return result;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Gets the result of trying to salvage the item normally
|
|
*
|
|
* @param player <p>The player trying to salvage the item</p>
|
|
* @param itemInHand <p>The item to be salvaged</p>
|
|
* @param extended <p>Whether extended salvage is enabled</p>
|
|
* @return <p>The result of attempting the salvage</p>
|
|
*/
|
|
@NotNull
|
|
private SalvageResult isNormalSalvage(@NotNull Player player, @NotNull ItemStack itemInHand, boolean extended) {
|
|
|
|
// As there is no recipe for netherite items, the check needs to be after the netherite salvage check
|
|
if (!SalvageHelper.isSalvageable(player.getServer(), itemInHand)) {
|
|
sendNPCMessage(this.npc, player, StringFormatter.replacePlaceholder(getSettings().getInvalidItemMessage(),
|
|
"{title}", getSettings().getScrapperTitle()));
|
|
BlacksmithPlugin.debug("Provided with non-salvage-able item " + itemInHand);
|
|
return new SalvageResult(SalvageMethod.SALVAGE, new ArrayList<>(), SalvageState.NO_SALVAGE, 0);
|
|
}
|
|
|
|
// Check if the item is enchanted, and whether this scrapper can salvage it
|
|
if (!itemInHand.getEnchantments().isEmpty() && !getSettings().salvageEnchanted()) {
|
|
sendNPCMessage(this.npc, player, getSettings().getCannotSalvageEnchantedMessage());
|
|
return new SalvageResult(SalvageMethod.SALVAGE, new ArrayList<>(), SalvageState.NO_SALVAGE, 0);
|
|
}
|
|
|
|
// Check if any salvage will be produced
|
|
RecipeResult recipeResult = getSalvage(itemInHand, extended);
|
|
SalvageMethod method = ItemHelper.isRepairable(itemInHand) ? SalvageMethod.SALVAGE : SalvageMethod.EXTENDED_SALVAGE;
|
|
boolean noUsefulSalvage = recipeResult == null || recipeResult.salvage().isEmpty();
|
|
if (noUsefulSalvage) {
|
|
sendNPCMessage(this.npc, player, getSettings().getTooDamagedMessage());
|
|
return new SalvageResult(method, new ArrayList<>(), SalvageState.NO_SALVAGE, 0);
|
|
} else {
|
|
return new SalvageResult(method, recipeResult.salvage(), SalvageState.FOUND_SALVAGE,
|
|
recipeResult.recipe().getResult().getAmount());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Gets the result of trying to salvage the item as an enchanted book
|
|
*
|
|
* @param player <p>The player trying to salvage the item</p>
|
|
* @param itemInHand <p>The item to be salvaged</p>
|
|
* @return <p>The result of attempting the salvage</p>
|
|
*/
|
|
private SalvageResult isEnchantedBookSalvage(@NotNull Player player, @NotNull ItemStack itemInHand) {
|
|
if (itemInHand.getType() != Material.ENCHANTED_BOOK ||
|
|
!(itemInHand.getItemMeta() instanceof EnchantmentStorageMeta)) {
|
|
return new SalvageResult(SalvageMethod.ENCHANTED_BOOK, new ArrayList<>(), SalvageState.INCORRECT_METHOD, 0);
|
|
}
|
|
|
|
if (!getSettings().splitEnchantedBook()) {
|
|
sendNPCMessage(this.npc, player, getSettings().getCannotSalvageEnchantedBookMessage());
|
|
return new SalvageResult(SalvageMethod.ENCHANTED_BOOK, new ArrayList<>(), SalvageState.NO_SALVAGE, 0);
|
|
}
|
|
|
|
if (SalvageHelper.getEnchantmentCount(itemInHand) <= 1) {
|
|
sendNPCMessage(this.npc, player, getSettings().getCannotSplitEnchantedBookFurtherMessage());
|
|
return new SalvageResult(SalvageMethod.ENCHANTED_BOOK, new ArrayList<>(), SalvageState.NO_SALVAGE, 0);
|
|
}
|
|
|
|
List<ItemStack> salvage = SalvageHelper.getEnchantedBookSalvage(itemInHand);
|
|
boolean noUsefulSalvage = salvage == null || salvage.isEmpty();
|
|
if (noUsefulSalvage) {
|
|
return new SalvageResult(SalvageMethod.ENCHANTED_BOOK, new ArrayList<>(), SalvageState.NO_SALVAGE, 0);
|
|
}
|
|
return new SalvageResult(SalvageMethod.ENCHANTED_BOOK, salvage, SalvageState.FOUND_SALVAGE, 1);
|
|
}
|
|
|
|
/**
|
|
* Gets the result of trying to salvage the item as a netherite applied item
|
|
*
|
|
* @param player <p>The player trying to salvage the item</p>
|
|
* @param itemInHand <p>The item to be salvaged</p>
|
|
* @return <p>The result of attempting the salvage</p>
|
|
*/
|
|
@NotNull
|
|
private SalvageResult isNetheriteSalvage(@NotNull Player player, @NotNull ItemStack itemInHand) {
|
|
if (!SmithPreset.BLACKSMITH.getFilteredMaterials(SmithPresetFilter.NETHERITE).contains(itemInHand.getType())) {
|
|
return new SalvageResult(SalvageMethod.NETHERITE, new ArrayList<>(), SalvageState.INCORRECT_METHOD, 0);
|
|
}
|
|
|
|
if (!getSettings().salvageNetherite()) {
|
|
sendNPCMessage(this.npc, player, getSettings().getCannotSalvageNetheriteMessage());
|
|
return new SalvageResult(SalvageMethod.NETHERITE, new ArrayList<>(), SalvageState.NO_SALVAGE, 0);
|
|
}
|
|
|
|
List<ItemStack> salvage = SalvageHelper.getNetheriteSalvage(itemInHand);
|
|
if (salvage == null || salvage.isEmpty()) {
|
|
return new SalvageResult(SalvageMethod.NETHERITE, new ArrayList<>(), SalvageState.NO_SALVAGE, 0);
|
|
}
|
|
|
|
return new SalvageResult(SalvageMethod.NETHERITE, salvage, SalvageState.FOUND_SALVAGE, 1);
|
|
}
|
|
|
|
/**
|
|
* Gets the result of trying to salvage the item as an armor trim
|
|
*
|
|
* @param player <p>The player trying to salvage the item</p>
|
|
* @param itemInHand <p>The item to be salvaged</p>
|
|
* @return <p>The result of attempting the salvage</p>
|
|
*/
|
|
@NotNull
|
|
private SalvageResult isArmorTrimSalvage(@NotNull Player player, @NotNull ItemStack itemInHand) {
|
|
if (!(itemInHand.getItemMeta() instanceof ArmorMeta armorMeta) || !armorMeta.hasTrim()) {
|
|
return new SalvageResult(SalvageMethod.ARMOR_TRIM, new ArrayList<>(), SalvageState.INCORRECT_METHOD, 0);
|
|
}
|
|
|
|
if (!getSettings().salvageArmorTrims()) {
|
|
sendNPCMessage(this.npc, player, getSettings().getCannotSalvageArmorTrimMessage());
|
|
return new SalvageResult(SalvageMethod.ARMOR_TRIM, new ArrayList<>(), SalvageState.NO_SALVAGE, 0);
|
|
}
|
|
|
|
List<ItemStack> salvage = SalvageHelper.getArmorTrimSalvage(itemInHand, armorMeta);
|
|
if (salvage == null || salvage.isEmpty()) {
|
|
sendNPCMessage(this.npc, player, getSettings().getArmorTrimSalvageNotFoundMessage());
|
|
return new SalvageResult(SalvageMethod.ARMOR_TRIM, new ArrayList<>(), SalvageState.NO_SALVAGE, 0);
|
|
}
|
|
|
|
return new SalvageResult(SalvageMethod.ARMOR_TRIM, salvage, SalvageState.FOUND_SALVAGE, 1);
|
|
}
|
|
|
|
/**
|
|
* Prints a message to the given player, explaining the cost of salvaging the held item
|
|
*
|
|
* @param player <p>The player that interacted with the scrapper</p>
|
|
* @param itemInHand <p>The item the player wants to salvage</p>
|
|
* @param cost <p>The cost of salvaging the item</p>
|
|
* @param salvageMethod <p>The type of salvage performed</p>
|
|
*/
|
|
private void printCostMessage(@NotNull Player player, @NotNull ItemStack itemInHand, @NotNull String cost,
|
|
@NotNull SalvageMethod salvageMethod) {
|
|
StringReplacer replacer = new StringReplacer();
|
|
replacer.add("{cost}", cost);
|
|
replacer.add("{item}", itemInHand.getType().name().toLowerCase().replace('_', ' '));
|
|
if (salvageMethod == SalvageMethod.ARMOR_TRIM) {
|
|
sendNPCMessage(this.npc, player, replacer.replace(getSettings().getArmorTrimCostMessage()));
|
|
} else if (salvageMethod == SalvageMethod.SALVAGE || salvageMethod == SalvageMethod.EXTENDED_SALVAGE) {
|
|
String expectedYield;
|
|
if (ItemHelper.getDamage(itemInHand) <= 0) {
|
|
expectedYield = getSettings().getFullSalvageMessage();
|
|
} else {
|
|
expectedYield = getSettings().getPartialSalvageMessage();
|
|
}
|
|
replacer.add("{yield}", expectedYield);
|
|
sendNPCMessage(this.npc, player, replacer.replace(getSettings().getCostMessage()));
|
|
} else if (salvageMethod == SalvageMethod.NETHERITE) {
|
|
sendNPCMessage(this.npc, player, replacer.replace(getSettings().getNetheriteCostMessage()));
|
|
} else if (salvageMethod == SalvageMethod.ENCHANTED_BOOK) {
|
|
StringReplacer replacer2 = new StringReplacer();
|
|
replacer2.add("{cost}", getEnchantedBookCost());
|
|
sendNPCMessage(this.npc, player, replacer2.replace(getSettings().getEnchantedBookCostMessage()));
|
|
} else {
|
|
BlacksmithPlugin.error("Unrecognized salvage method " + salvageMethod);
|
|
}
|
|
}
|
|
|
|
private String getEnchantedBookCost() {
|
|
// TODO: If both an item and money is required, print both requirements
|
|
// TODO: If only money is required, print the money requirement
|
|
// TODO: If an item requirement is set, print the item requirement
|
|
|
|
GlobalScrapperSettings scrapperSettings = BlacksmithPlugin.getInstance().getGlobalScrapperSettings();
|
|
/*String moneyCost = EconomyManager.format(scrapperSettings.getEnchantedBookSalvageCost());
|
|
//ItemStack itemCost = scrapperSettings.
|
|
if (scrapperSettings.requireMoneyAndItemForEnchantedBookSalvage()) {
|
|
// TODO: Print both with a + between them (if item has a special name, use that instead of the material name)
|
|
|
|
} else {
|
|
// TODO: If the item is not null, print it, otherwise print the monetary cost
|
|
}*/
|
|
return "";
|
|
}
|
|
|
|
@Override
|
|
protected boolean showExactTime() {
|
|
return BlacksmithPlugin.getInstance().getGlobalScrapperSettings().showExactTime();
|
|
}
|
|
|
|
/**
|
|
* Gets whether this scrapper can salvage the given item
|
|
*
|
|
* @param item <p>The item to check</p>
|
|
* @param salvageAbleItems <p>The items this scrapper can salvage</p>
|
|
* @param extended <p>Whether extended salvage is enabled</p>
|
|
* @return <p>True if the item can be theoretically salvaged</p>
|
|
*/
|
|
private boolean canBeSalvaged(@NotNull ItemStack item, @NotNull List<Material> salvageAbleItems, boolean extended) {
|
|
return item.getType() == Material.ENCHANTED_BOOK || ((extended || ItemHelper.isRepairable(item)) &&
|
|
(salvageAbleItems.isEmpty() || salvageAbleItems.contains(item.getType())));
|
|
}
|
|
|
|
/**
|
|
* Gets salvage for an item, if it's salvage-able
|
|
*
|
|
* @param item <p>The item to calculate salvage for</p>
|
|
* @param extended <p>Whether extended salvage is enabled</p>
|
|
* @return <p>The possible salvage, or null if not salvage-able</p>
|
|
*/
|
|
@Nullable
|
|
private RecipeResult getSalvage(@NotNull ItemStack item, boolean extended) {
|
|
// Get the salvage, for the item, but ignore some materials if set, and the item isn't at full durability
|
|
Set<Material> trashSalvage = BlacksmithPlugin.getInstance().getGlobalScrapperSettings().getTrashSalvage(
|
|
item.getType());
|
|
// Don't ignore salvage for fully repaired items
|
|
if (trashSalvage == null || ItemHelper.getDamage(item) == 0) {
|
|
trashSalvage = new HashSet<>();
|
|
}
|
|
|
|
return SalvageHelper.getSalvage(BlacksmithPlugin.getInstance().getServer(), item, trashSalvage, extended);
|
|
}
|
|
|
|
}
|